trident_driver.c revision 95b296d0
1/* 2 * Copyright 1992-2003 by Alan Hourihane, North Wales, UK. 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of Alan Hourihane not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. Alan Hourihane makes no representations 11 * about the suitability of this software for any purpose. It is provided 12 * "as is" without express or implied warranty. 13 * 14 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 * 22 * Author: Alan Hourihane, alanh@fairlite.demon.co.uk 23 * Re-written for XFree86 v4.0 24 * 25 * Previous driver (pre-XFree86 v4.0) by 26 * Alan Hourihane, alanh@fairlite.demon.co.uk 27 * David Wexelblat (major contributor) 28 * Massimiliano Ghilardi, max@Linuz.sns.it, some fixes to the 29 * clockchip programming code. 30 */ 31/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c,v 1.190 2004/01/21 22:31:54 alanh Exp $ */ 32 33#ifdef HAVE_CONFIG_H 34#include "config.h" 35#endif 36 37#include "fb.h" 38 39#include "mibank.h" 40#include "micmap.h" 41#include "xf86.h" 42#include "xf86_OSproc.h" 43#include "xf86Resources.h" 44#include "xf86Version.h" 45#include "xf86PciInfo.h" 46#include "xf86Pci.h" 47#include "xf86cmap.h" 48#include "vgaHW.h" 49#include "xf86RAC.h" 50#include "vbe.h" 51#include "dixstruct.h" 52#include "compiler.h" 53 54#include "mipointer.h" 55 56#include "mibstore.h" 57#include "shadow.h" 58#include "trident.h" 59#include "trident_regs.h" 60 61#ifdef XFreeXDGA 62#define _XF86DGA_SERVER_ 63#include <X11/extensions/xf86dgastr.h> 64#endif 65 66#include "globals.h" 67#define DPMS_SERVER 68#include <X11/extensions/dpms.h> 69 70#include "xf86xv.h" 71 72static const OptionInfoRec * TRIDENTAvailableOptions(int chipid, int busid); 73static void TRIDENTIdentify(int flags); 74static Bool TRIDENTProbe(DriverPtr drv, int flags); 75static Bool TRIDENTPreInit(ScrnInfoPtr pScrn, int flags); 76static Bool TRIDENTScreenInit(int Index, ScreenPtr pScreen, int argc, 77 char **argv); 78static Bool TRIDENTEnterVT(int scrnIndex, int flags); 79static void TRIDENTLeaveVT(int scrnIndex, int flags); 80static Bool TRIDENTCloseScreen(int scrnIndex, ScreenPtr pScreen); 81static Bool TRIDENTSaveScreen(ScreenPtr pScreen, int mode); 82 83/* Optional functions */ 84static void TRIDENTFreeScreen(int scrnIndex, int flags); 85static ModeStatus TRIDENTValidMode(int scrnIndex, DisplayModePtr mode, 86 Bool verbose, int flags); 87 88/* Internally used functions */ 89static Bool TRIDENTMapMem(ScrnInfoPtr pScrn); 90static Bool TRIDENTUnmapMem(ScrnInfoPtr pScrn); 91static void TRIDENTSave(ScrnInfoPtr pScrn); 92static void TRIDENTRestore(ScrnInfoPtr pScrn); 93static Bool TRIDENTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); 94static void TRIDENTBlockHandler(int, pointer, pointer, pointer); 95 96static void TRIDENTEnableMMIO(ScrnInfoPtr pScrn); 97static void TRIDENTDisableMMIO(ScrnInfoPtr pScrn); 98static void PC98TRIDENTInit(ScrnInfoPtr pScrn); 99static void PC98TRIDENTEnable(ScrnInfoPtr pScrn); 100static void PC98TRIDENTDisable(ScrnInfoPtr pScrn); 101static void PC98TRIDENT96xxInit(ScrnInfoPtr pScrn); 102static void PC98TRIDENT96xxEnable(ScrnInfoPtr pScrn); 103static void PC98TRIDENT96xxDisable(ScrnInfoPtr pScrn); 104static void PC98TRIDENT9385Init(ScrnInfoPtr pScrn); 105static void PC98TRIDENT9385Enable(ScrnInfoPtr pScrn); 106static void PC98TRIDENT9385Disable(ScrnInfoPtr pScrn); 107static int TRIDENTLcdDisplaySize (xf86MonPtr pMon); 108 109/* 110 * This is intentionally screen-independent. It indicates the binding 111 * choice made in the first PreInit. 112 */ 113static int pix24bpp = 0; 114 115#define TRIDENT_VERSION 4000 116#define TRIDENT_NAME "TRIDENT" 117#define TRIDENT_DRIVER_NAME "trident" 118#define TRIDENT_MAJOR_VERSION 1 119#define TRIDENT_MINOR_VERSION 2 120#define TRIDENT_PATCHLEVEL 3 121 122/* 123 * This contains the functions needed by the server after loading the driver 124 * module. It must be supplied, and gets passed back by the SetupProc 125 * function in the dynamic case. In the static case, a reference to this 126 * is compiled in, and this requires that the name of this DriverRec be 127 * an upper-case version of the driver name. 128 */ 129 130_X_EXPORT DriverRec TRIDENT = { 131 TRIDENT_VERSION, 132 TRIDENT_DRIVER_NAME, 133 TRIDENTIdentify, 134 TRIDENTProbe, 135 TRIDENTAvailableOptions, 136 NULL, 137 0 138}; 139 140static SymTabRec TRIDENTChipsets[] = { 141 { TVGA9000, "tvga9000" }, 142 { TVGA9000i, "tvga9000i" }, 143 { TVGA8900C, "tvga8900c" }, 144 { TVGA8900D, "tvga8900d" }, 145 { TVGA9200CXr, "tvga9200cxr" }, 146 { TGUI9400CXi, "tgui9400cxi" }, 147 { CYBER9320, "cyber9320" }, 148 { CYBER9388, "cyber9388" }, 149 { CYBER9397, "cyber9397" }, 150 { CYBER9397DVD, "cyber9397dvd" }, 151 { CYBER9520, "cyber9520" }, 152 { CYBER9525DVD, "cyber9525dvd" }, 153 { CYBERBLADEE4, "cyberblade/e4" }, 154 { TGUI9420DGi, "tgui9420dgi" }, 155 { TGUI9440AGi, "tgui9440agi" }, 156 { TGUI9660, "tgui9660" }, 157 { TGUI9680, "tgui9680" }, 158 { PROVIDIA9682, "providia9682" }, 159 { PROVIDIA9685, "providia9685" }, 160 { CYBER9382, "cyber9382" }, 161 { CYBER9385, "cyber9385" }, 162 { IMAGE975, "3dimage975" }, 163 { IMAGE985, "3dimage985" }, 164 { BLADE3D, "blade3d" }, 165 { CYBERBLADEI7, "cyberbladei7" }, 166 { CYBERBLADEI7D, "cyberbladei7d" }, 167 { CYBERBLADEI1, "cyberbladei1" }, 168 { CYBERBLADEI1D, "cyberbladei1d" }, 169 { CYBERBLADEAI1, "cyberbladeAi1" }, 170 { CYBERBLADEAI1D, "cyberbladeAi1d" }, 171 { BLADEXP, "bladeXP" }, 172 { CYBERBLADEXPAI1, "cyberbladeXPAi1" }, 173 { CYBERBLADEXP4, "cyberbladeXP4" }, 174 { XP5, "XP5" }, 175 { -1, NULL } 176}; 177 178static IsaChipsets TRIDENTISAchipsets[] = { 179 { TVGA9000, RES_EXCLUSIVE_VGA }, 180 { TVGA9000i, RES_EXCLUSIVE_VGA }, 181 { TVGA8900C, RES_EXCLUSIVE_VGA }, 182 { TVGA8900D, RES_EXCLUSIVE_VGA }, 183 { TVGA9200CXr, RES_EXCLUSIVE_VGA }, 184 { TGUI9400CXi, RES_EXCLUSIVE_VGA }, 185 { CYBER9320, RES_EXCLUSIVE_VGA }, 186 { TGUI9440AGi, RES_EXCLUSIVE_VGA }, 187 { -1, RES_UNDEFINED } 188}; 189 190static PciChipsets TRIDENTPciChipsets[] = { 191 { CYBER9320, PCI_CHIP_9320, RES_SHARED_VGA }, 192 { CYBER9388, PCI_CHIP_9388, RES_SHARED_VGA }, 193 { CYBER9397, PCI_CHIP_9397, RES_SHARED_VGA }, 194 { CYBER9397DVD, PCI_CHIP_939A, RES_SHARED_VGA }, 195 { CYBER9520, PCI_CHIP_9520, RES_SHARED_VGA }, 196 { CYBER9525DVD, PCI_CHIP_9525, RES_SHARED_VGA }, 197 { CYBERBLADEE4, PCI_CHIP_9540, RES_SHARED_VGA }, 198 { TGUI9420DGi, PCI_CHIP_9420, RES_SHARED_VGA }, 199 { TGUI9440AGi, PCI_CHIP_9440, RES_SHARED_VGA }, 200 { TGUI9660, PCI_CHIP_9660, RES_SHARED_VGA }, 201 { TGUI9680, PCI_CHIP_9660, RES_SHARED_VGA }, 202 { PROVIDIA9682, PCI_CHIP_9660, RES_SHARED_VGA }, 203 { PROVIDIA9685, PCI_CHIP_9660, RES_SHARED_VGA }, 204 { CYBER9382, PCI_CHIP_9660, RES_SHARED_VGA }, 205 { CYBER9385, PCI_CHIP_9660, RES_SHARED_VGA }, 206 { IMAGE975, PCI_CHIP_9750, RES_SHARED_VGA }, 207 { IMAGE985, PCI_CHIP_9850, RES_SHARED_VGA }, 208 { BLADE3D, PCI_CHIP_9880, RES_SHARED_VGA }, 209 { CYBERBLADEI7, PCI_CHIP_8400, RES_SHARED_VGA }, 210 { CYBERBLADEI7D, PCI_CHIP_8420, RES_SHARED_VGA }, 211 { CYBERBLADEI1, PCI_CHIP_8500, RES_SHARED_VGA }, 212 { CYBERBLADEI1D, PCI_CHIP_8520, RES_SHARED_VGA }, 213 { CYBERBLADEAI1, PCI_CHIP_8600, RES_SHARED_VGA }, 214 { CYBERBLADEAI1D, PCI_CHIP_8620, RES_SHARED_VGA }, 215 { BLADEXP, PCI_CHIP_9910, RES_SHARED_VGA }, 216 { CYBERBLADEXPAI1, PCI_CHIP_8820, RES_SHARED_VGA }, 217 { CYBERBLADEXP4, PCI_CHIP_2100, RES_SHARED_VGA }, 218 { XP5, PCI_CHIP_2200, RES_SHARED_VGA }, 219 { -1, -1, RES_UNDEFINED } 220}; 221 222typedef enum { 223 OPTION_ACCELMETHOD, 224 OPTION_SW_CURSOR, 225 OPTION_PCI_RETRY, 226 OPTION_RGB_BITS, 227 OPTION_NOACCEL, 228 OPTION_SETMCLK, 229 OPTION_MUX_THRESHOLD, 230 OPTION_SHADOW_FB, 231 OPTION_ROTATE, 232 OPTION_MMIO_ONLY, 233 OPTION_VIDEO_KEY, 234 OPTION_NOMMIO, 235 OPTION_NOPCIBURST, 236 OPTION_CYBER_SHADOW, 237 OPTION_CYBER_STRETCH, 238 OPTION_XV_HSYNC, 239 OPTION_XV_VSYNC, 240 OPTION_XV_BSKEW, 241 OPTION_XV_RSKEW, 242 OPTION_FP_DELAY, 243 OPTION_1400_DISPLAY, 244 OPTION_DISPLAY, 245 OPTION_GB, 246 OPTION_TV_CHIPSET, 247 OPTION_TV_SIGNALMODE 248} TRIDENTOpts; 249 250static const OptionInfoRec TRIDENTOptions[] = { 251 { OPTION_ACCELMETHOD, "AccelMethod", OPTV_ANYSTR, {0}, FALSE }, 252 { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, 253 { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE }, 254 { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 255 { OPTION_SETMCLK, "SetMClk", OPTV_FREQ, {0}, FALSE }, 256 { OPTION_MUX_THRESHOLD, "MUXThreshold", OPTV_INTEGER, {0}, FALSE }, 257 { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, 258 { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, 259 { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, 260 { OPTION_NOMMIO, "NoMMIO", OPTV_BOOLEAN, {0}, FALSE }, 261 { OPTION_NOPCIBURST, "NoPciBurst", OPTV_BOOLEAN, {0}, FALSE }, 262 { OPTION_MMIO_ONLY, "MMIOonly", OPTV_BOOLEAN, {0}, FALSE }, 263 { OPTION_CYBER_SHADOW, "CyberShadow", OPTV_BOOLEAN, {0}, FALSE }, 264 { OPTION_CYBER_STRETCH, "CyberStretch", OPTV_BOOLEAN, {0}, FALSE }, 265 { OPTION_XV_HSYNC, "XvHsync", OPTV_INTEGER, {0}, FALSE }, 266 { OPTION_XV_VSYNC, "XvVsync", OPTV_INTEGER, {0}, FALSE }, 267 { OPTION_XV_BSKEW, "XvBskew", OPTV_INTEGER, {0}, FALSE }, 268 { OPTION_XV_RSKEW, "XvRskew", OPTV_INTEGER, {0}, FALSE }, 269 { OPTION_FP_DELAY, "FpDelay", OPTV_INTEGER, {0}, FALSE }, 270 { OPTION_1400_DISPLAY, "Display1400", OPTV_BOOLEAN, {0}, FALSE }, 271 { OPTION_DISPLAY, "Display", OPTV_ANYSTR, {0}, FALSE }, 272 { OPTION_GB, "GammaBrightness", OPTV_ANYSTR, {0}, FALSE }, 273 { OPTION_TV_CHIPSET, "TVChipset", OPTV_ANYSTR, {0}, FALSE }, 274 { OPTION_TV_SIGNALMODE, "TVSignal", OPTV_INTEGER, {0}, FALSE }, 275 { -1, NULL, OPTV_NONE, {0}, FALSE } 276}; 277 278/* Clock Limits */ 279static int ClockLimit[] = { 280 80000, 281 80000, 282 80000, 283 80000, 284 80000, 285 80000, 286 80000, 287 80000, 288 80000, 289 80000, 290 80000, 291 80000, 292 80000, 293 80000, 294 90000, 295 90000, 296 135000, 297 135000, 298 170000, 299 170000, 300 170000, 301 170000, 302 170000, 303 170000, 304 170000, 305 230000, 306 230000, 307 230000, 308 230000, 309 230000, 310 230000, 311 230000, 312 230000, 313 230000, 314 230000, 315 230000, 316 230000, 317 230000, 318 230000, 319 230000, 320 230000, 321}; 322 323static int ClockLimit16bpp[] = { 324 40000, 325 40000, 326 40000, 327 40000, 328 40000, 329 40000, 330 40000, 331 40000, 332 40000, 333 40000, 334 40000, 335 40000, 336 40000, 337 40000, 338 45000, 339 45000, 340 90000, 341 90000, 342 135000, 343 135000, 344 170000, 345 170000, 346 170000, 347 170000, 348 170000, 349 230000, 350 230000, 351 230000, 352 230000, 353 230000, 354 230000, 355 230000, 356 230000, 357 230000, 358 230000, 359 230000, 360 230000, 361 230000, 362 230000, 363 230000, 364 230000, 365}; 366 367static int ClockLimit24bpp[] = { 368 25180, 369 25180, 370 25180, 371 25180, 372 25180, 373 25180, 374 25180, 375 25180, 376 25180, 377 25180, 378 25180, 379 25180, 380 25180, 381 25180, 382 25180, 383 25180, 384 40000, 385 40000, 386 70000, 387 70000, 388 70000, 389 115000, 390 115000, 391 115000, 392 115000, 393 115000, 394 115000, 395 115000, 396 115000, 397 115000, 398 115000, 399 115000, 400 115000, 401 115000, 402 115000, 403 115000, 404 115000, 405 115000, 406 115000, 407 115000, 408 115000, 409}; 410 411static int ClockLimit32bpp[] = { 412 25180, 413 25180, 414 25180, 415 25180, 416 25180, 417 25180, 418 25180, 419 25180, 420 25180, 421 25180, 422 25180, 423 25180, 424 25180, 425 25180, 426 25180, 427 25180, 428 40000, 429 40000, 430 70000, 431 70000, 432 70000, 433 115000, 434 115000, 435 115000, 436 115000, 437 115000, 438 115000, 439 115000, 440 115000, 441 115000, 442 115000, 443 115000, 444 115000, 445 115000, 446 115000, 447 115000, 448 115000, 449 115000, 450 115000, 451 115000, 452 115000, 453 115000, 454}; 455 456/* 457 * These are fixed modelines for all physical display dimensions the 458 * chipsets supports on FPs. Most of them are not tested yet. 459 */ 460#if 0 461tridentLCD LCD[] = { /* 0 3 4 5 6 7 10 11 16 */ 462 { 0,"640x480",25200,0x5f,0x82,0x54,0x80,0xb,0x3e,0xea,0x8c,0xb,0x08}, 463 { 1,"800x600",40000,0x7f,0x99,0x69,0x99,0x72,0xf0,0x59,0x2d,0x5e,0x08}, 464 { 2,"1024x768",65000,0xa3,/*0x6*/ 0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08}, 465 { 3,"1024x768",65000,0xa3,/*0x6*/ 0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08}, /*0x96*/ 466 { 4,"1280x1024",108000,0xa3,0x6,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08}, 467 { 5,"1024x600",50500 ,0xa3,0x6,0x8f,0xa0,0xb,0x3e,0xea,0x8c,0xb,0x08}, 468 { 0xff,"", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 469}; 470#else 471#if 0 472tridentLCD LCD[] = { 473 { 1,640,480,25200,0x5f,0x82,0x54,0x80,0xb,0x3e,0xea,0x8c,0xb,0x08}, 474 { 3,800,600,40000,0x7f,0x82,0x6b,0x1b,0x72,0xf8,0x58,0x8c,0x72,0x08}, 475 { 2,1024,768,65000,0xa3,/*0x6*/0x98,0x8f,0xa0,0x24,0xf5,0x0f,0x24,0x0a,0x08}, 476 { 0,1280,1024,108000,0xce,0x81,0xa6,0x9a,0x27,0x50,0x00,0x03,0x26,0xa8}, 477 { 0xff,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 478}; 479#else 480tridentLCD LCD[] = { 481 { 1,640,480,25200,0x5f,0x80,0x52,0x1e,0xb,0x3e,0xea,0x0c,0xb,0x08}, 482 { 3,800,600,40000,0x7f,0x00,0x69,0x7f,0x72,0xf0,0x59,0x0d,0x00,0x08}, 483 { 2,1024,768,65000,0xa3,0x00,0x84,0x94,0x24,0xf5,0x03,0x09,0x24,0x08}, 484 { 0,1280,1024,108000,0xce,0x91,0xa6,0x14,0x28,0x5a,0x01,0x04,0x28,0xa8}, 485 { 4,1400,1050,122000,0xe6,0x8d,0xba,0x1d,0x38,0x00,0x1c,0x28,0x28,0xf8}, 486 { 0xff,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 487}; 488#endif 489#endif 490 491static const char *xaaSymbols[] = { 492 "XAAGetCopyROP", 493 "XAACreateInfoRec", 494 "XAADestroyInfoRec", 495 "XAAInit", 496 "XAAGetPatternROP", 497 NULL 498}; 499 500const char *exaSymbols[] = { 501 "exaDriverAlloc", 502 "exaDriverInit", 503 "exaDriverFini", 504 "exaOffscreenAlloc", 505 "exaOffscreenFree", 506 NULL 507}; 508 509static const char *vgahwSymbols[] = { 510 "vgaHWBlankScreenWeak", 511 "vgaHWFreeHWRec", 512 "vgaHWGetHWRec", 513 "vgaHWGetIOBase", 514 "vgaHWGetIndex", 515 "vgaHWInit", 516 "vgaHWLock", 517 "vgaHWMapMem", 518 "vgaHWProtectWeak", 519 "vgaHWRestore", 520 "vgaHWSave", 521 "vgaHWSaveScreen", 522 "vgaHWSetMmioFuncs", 523 "vgaHWUnlock", 524 NULL 525}; 526 527static const char *fbSymbols[] = { 528 "fbPictureInit", 529 "fbScreenInit", 530 NULL 531}; 532 533static const char *ramdacSymbols[] = { 534 "xf86CreateCursorInfoRec", 535 "xf86DestroyCursorInfoRec", 536 "xf86InitCursor", 537 NULL 538}; 539 540static const char *ddcSymbols[] = { 541 "xf86PrintEDID", 542 "xf86SetDDCproperties", 543 NULL 544}; 545 546static const char *i2cSymbols[] = { 547 "xf86CreateI2CBusRec", 548 "xf86I2CBusInit", 549 NULL 550}; 551 552static const char *int10Symbols[] = { 553 "xf86ExecX86int10", 554 "xf86FreeInt10", 555 "xf86InitInt10", 556 NULL 557}; 558 559static const char *shadowSymbols[] = { 560 "shadowInit", 561 NULL 562}; 563 564static const char *vbeSymbols[] = { 565 "VBEInit", 566 "vbeDoEDID", 567 "vbeFree", 568 NULL 569}; 570 571#ifdef XFree86LOADER 572 573static MODULESETUPPROTO(tridentSetup); 574 575static XF86ModuleVersionInfo tridentVersRec = 576{ 577 "trident", 578 MODULEVENDORSTRING, 579 MODINFOSTRING1, 580 MODINFOSTRING2, 581 XORG_VERSION_CURRENT, 582 TRIDENT_MAJOR_VERSION, TRIDENT_MINOR_VERSION, TRIDENT_PATCHLEVEL, 583 ABI_CLASS_VIDEODRV, /* This is a video driver */ 584 ABI_VIDEODRV_VERSION, 585 MOD_CLASS_VIDEODRV, 586 {0,0,0,0} 587}; 588 589_X_EXPORT XF86ModuleData tridentModuleData = { 590 &tridentVersRec, 591 tridentSetup, 592 NULL 593}; 594 595pointer 596tridentSetup(pointer module, pointer opts, int *errmaj, int *errmin) 597{ 598 static Bool setupDone = FALSE; 599 600 if (!setupDone) { 601 setupDone = TRUE; 602 xf86AddDriver(&TRIDENT, module, 0); 603 LoaderRefSymLists(vgahwSymbols, fbSymbols, i2cSymbols, vbeSymbols, 604 ramdacSymbols, int10Symbols, 605 xaaSymbols, exaSymbols, shadowSymbols, NULL); 606 return (pointer)TRUE; 607 } 608 609 if (errmaj) *errmaj = LDR_ONCEONLY; 610 return NULL; 611} 612 613#endif /* XFree86LOADER */ 614 615static Bool 616TRIDENTGetRec(ScrnInfoPtr pScrn) 617{ 618 /* 619 * Allocate an TRIDENTRec, and hook it into pScrn->driverPrivate. 620 * pScrn->driverPrivate is initialised to NULL, so we can check if 621 * the allocation has already been done. 622 */ 623 if (pScrn->driverPrivate != NULL) 624 return TRUE; 625 626 pScrn->driverPrivate = xnfcalloc(sizeof(TRIDENTRec), 1); 627 /* Initialise it */ 628 629 return TRUE; 630} 631 632static void 633TRIDENTFreeRec(ScrnInfoPtr pScrn) 634{ 635 if (pScrn->driverPrivate == NULL) 636 return; 637 xfree(pScrn->driverPrivate); 638 pScrn->driverPrivate = NULL; 639} 640 641static void 642TRIDENTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) 643{ 644 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 645 CARD8 DPMSCont, PMCont, temp; 646 647 if (!pScrn->vtSema) 648 return; 649 650 OUTB(0x3C4, 0x0E); 651 temp = INB(0x3C5); 652 OUTB(0x3C5, 0xC2); 653 OUTB(0x83C8, 0x04); /* Read DPMS Control */ 654 PMCont = INB(0x83C6) & 0xFC; 655 OUTB(0x3CE, 0x23); 656 DPMSCont = INB(0x3CF) & 0xFC; 657 switch (PowerManagementMode) 658 { 659 case DPMSModeOn: 660 /* Screen: On, HSync: On, VSync: On */ 661 PMCont |= 0x03; 662 DPMSCont |= 0x00; 663 break; 664 case DPMSModeStandby: 665 /* Screen: Off, HSync: Off, VSync: On */ 666 PMCont |= 0x02; 667 DPMSCont |= 0x01; 668 break; 669 case DPMSModeSuspend: 670 /* Screen: Off, HSync: On, VSync: Off */ 671 PMCont |= 0x02; 672 DPMSCont |= 0x02; 673 break; 674 case DPMSModeOff: 675 /* Screen: Off, HSync: Off, VSync: Off */ 676 PMCont |= 0x00; 677 DPMSCont |= 0x03; 678 break; 679 } 680 OUTB(0x3CF, DPMSCont); 681 OUTB(0x83C8, 0x04); 682 OUTB(0x83C6, PMCont); 683 OUTW(0x3C4, (temp<<8) | 0x0E); 684} 685 686static void 687TRIDENTBlockHandler ( 688 int i, 689 pointer blockData, 690 pointer pTimeout, 691 pointer pReadmask 692){ 693 ScreenPtr pScreen = screenInfo.screens[i]; 694 ScrnInfoPtr pScrn = xf86Screens[i]; 695 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 696 697 pScreen->BlockHandler = pTrident->BlockHandler; 698 (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); 699 pScreen->BlockHandler = TRIDENTBlockHandler; 700 701 if(pTrident->VideoTimerCallback) { 702 UpdateCurrentTime(); 703 (*pTrident->VideoTimerCallback)(pScrn, currentTime.milliseconds); 704 } 705} 706 707static const OptionInfoRec * 708TRIDENTAvailableOptions(int chipid, int busid) 709{ 710 return TRIDENTOptions; 711} 712 713/* Mandatory */ 714static void 715TRIDENTIdentify(int flags) 716{ 717 xf86PrintChipsets(TRIDENT_NAME, "driver for Trident chipsets", TRIDENTChipsets); 718} 719 720Bool 721TRIDENTClockSelect(ScrnInfoPtr pScrn, int no) 722{ 723 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 724 unsigned char temp; 725 726 /* 727 * CS0 and CS1 are in MiscOutReg 728 * 729 * For 8900B, 8900C, 8900CL and 9000, CS2 is bit 0 of 730 * New Mode Control Register 2. 731 * 732 * For 8900CL, CS3 is bit 4 of Old Mode Control Register 1. 733 * 734 * For 9000, CS3 is bit 6 of New Mode Control Register 2. 735 * 736 * For TGUI, we don't use the ClockSelect function at all. 737 */ 738 switch(no) { 739 case CLK_REG_SAVE: 740 pTrident->SaveClock1 = INB(0x3CC); 741 if (pTrident->Chipset != TVGA8800CS) { 742 if ( (pScrn->numClocks == 16) && 743 (pTrident->Chipset != TVGA9000) && 744 (pTrident->Chipset != TVGA9000i) ) 745 { 746 OUTW(0x3C4, 0x000B); /* Switch to Old Mode */ 747 OUTB(0x3C4, 0x0E); pTrident->SaveClock3 = INB(0x3C5); 748 } 749 OUTB(0x3C4, 0x0B); 750 INB(0x3C5); /* Now to New Mode */ 751 OUTB(0x3C4, 0x0D); pTrident->SaveClock2 = INB(0x3C5); 752 } 753 break; 754 case CLK_REG_RESTORE: 755 OUTB(0x3C2, pTrident->SaveClock1); 756 if (pTrident->Chipset != TVGA8800CS) { 757 if ( (pScrn->numClocks == 16) && 758 (pTrident->Chipset != TVGA9000) && 759 (pTrident->Chipset != TVGA9000i) ) 760 { 761 OUTW(0x3C4, 0x000B); /* Switch to Old Mode */ 762 OUTW(0x3C4, (pTrident->SaveClock3 << 8) | 0x0E); 763 } 764 OUTB(0x3C4, 0x0B); 765 INB(0x3C5); /* Now to New Mode */ 766 OUTW(0x3C4, (pTrident->SaveClock2 << 8) | 0x0D); 767 } 768 break; 769 default: 770 /* 771 * Do CS0 and CS1 772 */ 773 temp = INB(0x3CC); 774 OUTB(0x3C2, (temp & 0xF3) | ((no << 2) & 0x0C)); 775 if (pTrident->Chipset != TVGA8800CS) { 776 if ( (pScrn->numClocks == 16) && 777 (pTrident->Chipset != TVGA9000) && 778 (pTrident->Chipset != TVGA9000i) ) 779 { 780 /* 781 * Go to Old Mode for CS3. 782 */ 783 OUTW(0x3C4, 0x000B); /* Switch to Old Mode */ 784 OUTB(0x3C4, 0x0E); 785 temp = INB(0x3C5) & 0xEF; 786 temp |= (no & 0x08) << 1; 787 OUTB(0x3C5, temp); 788 } 789 /* 790 * Go to New Mode for CS2 and TVGA9000 CS3. 791 */ 792 OUTB(0x3C4, 0x0B); 793 INB(0x3C5); /* Now to New Mode */ 794 OUTB(0x3C4, 0x0D); 795 /* 796 * Bits 1 & 2 are dividers - set to 0 to get no 797 * clock division. 798 */ 799 temp = INB(0x3C5) & 0xF8; 800 temp |= (no & 0x04) >> 2; 801 if ( (pTrident->Chipset == TVGA9000) || 802 (pTrident->Chipset == TVGA9000i) ) 803 { 804 temp &= ~0x40; 805 temp |= (no & 0x08) << 3; 806 } 807 OUTB(0x3C5, temp); 808 } 809 } 810 return(TRUE); 811} 812 813static int 814TridentFindIsaDevice(GDevPtr dev) 815{ 816 int found = -1; 817 unsigned char temp, origVal, newVal; 818 819 /* 820 * Check first that we have a Trident card. 821 */ 822 outb(0x3C4, 0x0B); 823 temp = inb(0x3C5); /* Save old value */ 824 outb(0x3C4, 0x0B); /* Switch to Old Mode */ 825 outb(0x3C5, 0x00); 826 inb(0x3C5); /* Now to New Mode */ 827 outb(0x3C4, 0x0E); 828 origVal = inb(0x3C5); 829 outb(0x3C5, 0x00); 830 newVal = inb(0x3C5) & 0x0F; 831 outb(0x3C5, (origVal ^ 0x02)); 832 833 /* 834 * Is it a Trident card ?? 835 */ 836 if (newVal != 2) { 837 /* 838 * Nope, so quit 839 */ 840 outb(0x3C4, 0x0B); /* Restore value of 0x0B */ 841 outb(0x3C5, temp); 842 outb(0x3C4, 0x0E); 843 outb(0x3C5, origVal); 844 return found; 845 } 846 847 outb(0x3C4, 0x0B); 848 temp = inb(0x3C5); 849 switch (temp) { 850 case 0x01: 851 found = TVGA8800BR; 852 break; 853 case 0x02: 854 found = TVGA8800CS; 855 break; 856 case 0x03: 857 found = TVGA8900B; 858 break; 859 case 0x04: 860 case 0x13: 861 found = TVGA8900C; 862 break; 863 case 0x23: 864 found = TVGA9000; 865 break; 866 case 0x33: 867 found = TVGA8900D; 868 break; 869 case 0x43: 870 found = TVGA9000i; 871 break; 872 case 0x53: 873 found = TVGA9200CXr; 874 break; 875 case 0x63: 876 found = TVGA9100B; 877 break; 878 case 0x73: 879 case 0xC3: 880 found = TGUI9420DGi; 881 break; 882 case 0x83: 883 found = TVGA8200LX; 884 break; 885 case 0x93: 886 found = TGUI9400CXi; 887 break; 888 case 0xA3: 889 found = CYBER9320; 890 break; 891 case 0xD3: 892 found = TGUI9660; 893 break; 894 case 0xE3: 895 found = TGUI9440AGi; 896 break; 897 case 0xF3: 898 found = TGUI9430DGi; 899 break; 900 } 901 return found; 902} 903 904 905/* Mandatory */ 906static Bool 907TRIDENTProbe(DriverPtr drv, int flags) 908{ 909 int i; 910 GDevPtr *devSections; 911 int *usedChips = NULL; 912 int numDevSections; 913 int numUsed; 914 Bool foundScreen = FALSE; 915 916 if ((numDevSections = xf86MatchDevice(TRIDENT_DRIVER_NAME, 917 &devSections)) <= 0) { 918 /* 919 * There's no matching device section in the config file, so quit 920 * now. 921 */ 922 return FALSE; 923 } 924 925 /* 926 * While we're VGA-dependent, can really only have one such instance, but 927 * we'll ignore that. 928 */ 929 930 /* 931 * We need to probe the hardware first. We then need to see how this 932 * fits in with what is given in the config file, and allow the config 933 * file info to override any contradictions. 934 */ 935 936 /* 937 * All of the cards this driver supports are PCI, so the "probing" just 938 * amounts to checking the PCI data that the server has already collected. 939 */ 940 if (xf86GetPciVideoInfo()) { 941 numUsed = xf86MatchPciInstances(TRIDENT_NAME, PCI_VENDOR_TRIDENT, 942 TRIDENTChipsets, TRIDENTPciChipsets, devSections, 943 numDevSections, drv, &usedChips); 944 945 if (numUsed > 0) { 946 if (flags & PROBE_DETECT) 947 foundScreen = TRUE; 948 else for (i = 0; i < numUsed; i++) { 949 ScrnInfoPtr pScrn = NULL; 950 951 if ((pScrn = xf86ConfigPciEntity(pScrn, 0,usedChips[i], 952 TRIDENTPciChipsets, NULL, 953 NULL, NULL, NULL, NULL))) { 954 /* Fill in what we can of the ScrnInfoRec */ 955 pScrn->driverVersion = TRIDENT_VERSION; 956 pScrn->driverName = TRIDENT_DRIVER_NAME; 957 pScrn->name = TRIDENT_NAME; 958 pScrn->Probe = TRIDENTProbe; 959 pScrn->PreInit = TRIDENTPreInit; 960 pScrn->ScreenInit = TRIDENTScreenInit; 961 pScrn->SwitchMode = TRIDENTSwitchMode; 962 pScrn->AdjustFrame = TRIDENTAdjustFrame; 963 pScrn->EnterVT = TRIDENTEnterVT; 964 pScrn->LeaveVT = TRIDENTLeaveVT; 965 pScrn->FreeScreen = TRIDENTFreeScreen; 966 pScrn->ValidMode = TRIDENTValidMode; 967 foundScreen = TRUE; 968 } 969 } 970 xfree(usedChips); 971 } 972 } 973 974 /* Isa Bus */ 975 numUsed = xf86MatchIsaInstances(TRIDENT_NAME,TRIDENTChipsets, 976 TRIDENTISAchipsets, 977 drv,TridentFindIsaDevice,devSections, 978 numDevSections,&usedChips); 979 if (numUsed > 0) { 980 if (flags & PROBE_DETECT) 981 foundScreen = TRUE; 982 else for (i = 0; i < numUsed; i++) { 983 ScrnInfoPtr pScrn = NULL; 984 if ((pScrn = xf86ConfigIsaEntity(pScrn,0,usedChips[i], 985 TRIDENTISAchipsets,NULL, 986 NULL,NULL,NULL,NULL))) { 987 pScrn->driverVersion = TRIDENT_VERSION; 988 pScrn->driverName = TRIDENT_DRIVER_NAME; 989 pScrn->name = TRIDENT_NAME; 990 pScrn->Probe = TRIDENTProbe; 991 pScrn->PreInit = TRIDENTPreInit; 992 pScrn->ScreenInit = TRIDENTScreenInit; 993 pScrn->SwitchMode = TRIDENTSwitchMode; 994 pScrn->AdjustFrame = TRIDENTAdjustFrame; 995 pScrn->EnterVT = TRIDENTEnterVT; 996 pScrn->LeaveVT = TRIDENTLeaveVT; 997 pScrn->FreeScreen = TRIDENTFreeScreen; 998 pScrn->ValidMode = TRIDENTValidMode; 999 foundScreen = TRUE; 1000 } 1001 } 1002 xfree(usedChips); 1003 } 1004 1005 xfree(devSections); 1006 return foundScreen; 1007} 1008 1009/* 1010 * GetAccelPitchValues - 1011 * 1012 * This function returns a list of display width (pitch) values that can 1013 * be used in accelerated mode. 1014 */ 1015static int * 1016GetAccelPitchValues(ScrnInfoPtr pScrn) 1017{ 1018 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 1019 int *linePitches = NULL; 1020 int lines[4] = { 512, 1024, 2048, 4096 }; /* 9440AGi */ 1021 int i, n = 0; 1022 1023 if (pTrident->Chipset >= BLADEXP) { 1024 lines[0] = 1024; 1025 lines[1] = 2048; 1026 lines[2] = 4096; 1027 lines[3] = 8192; 1028 } 1029 1030 for (i = 0; i < 4; i++) { 1031 n++; 1032 linePitches = xnfrealloc(linePitches, n * sizeof(int)); 1033 linePitches[n - 1] = lines[i]; 1034 } 1035 1036 /* Mark the end of the list */ 1037 if (n > 0) { 1038 linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int)); 1039 linePitches[n] = 0; 1040 } 1041 return linePitches; 1042} 1043 1044static void 1045TRIDENTProbeDDC(ScrnInfoPtr pScrn, int index) 1046{ 1047 vbeInfoPtr pVbe; 1048 if (xf86LoadSubModule(pScrn, "vbe")) { 1049 pVbe = VBEInit(NULL,index); 1050 ConfiguredMonitor = vbeDoEDID(pVbe, NULL); 1051 vbeFree(pVbe); 1052 } 1053} 1054 1055/* Mandatory */ 1056static Bool 1057TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) 1058{ 1059 TRIDENTPtr pTrident; 1060 vgaHWPtr hwp; 1061 MessageType from; 1062 CARD8 videoram, videorammask; 1063 char *ramtype = NULL, *chipset = NULL; 1064 Bool Support24bpp; 1065 int vgaIOBase; 1066 float mclk; 1067 double real; 1068 int i, NoClocks = 16; 1069 CARD8 revision; 1070 ClockRangePtr clockRanges; 1071 Bool ddcLoaded = FALSE; 1072 xf86MonPtr pMon = NULL; 1073 char *s; 1074 Bool tmp_bool; 1075 1076 /* Allocate the TRIDENTRec driverPrivate */ 1077 if (!TRIDENTGetRec(pScrn)) { 1078 return FALSE; 1079 } 1080 pTrident = TRIDENTPTR(pScrn); 1081 pTrident->pScrn = pScrn; 1082 1083 if (pScrn->numEntities > 1) 1084 return FALSE; 1085 /* This is the general case */ 1086 for (i = 0; i<pScrn->numEntities; i++) { 1087 pTrident->pEnt = xf86GetEntityInfo(pScrn->entityList[i]); 1088 if (pTrident->pEnt->resources) return FALSE; 1089 pTrident->Chipset = pTrident->pEnt->chipset; 1090 pScrn->chipset = (char *)xf86TokenToString(TRIDENTChipsets, 1091 pTrident->pEnt->chipset); 1092 /* This driver can handle ISA and PCI buses */ 1093 if (pTrident->pEnt->location.type == BUS_PCI) { 1094 pTrident->PciInfo = xf86GetPciInfoForEntity(pTrident->pEnt->index); 1095 pTrident->PciTag = pciTag(pTrident->PciInfo->bus, 1096 pTrident->PciInfo->device, 1097 pTrident->PciInfo->func); 1098 pTrident->Linear = TRUE; 1099 } else { 1100 pTrident->Linear = FALSE; 1101 } 1102 } 1103 1104 if (flags & PROBE_DETECT) { 1105 TRIDENTProbeDDC(pScrn, pTrident->pEnt->index); 1106 return TRUE; 1107 } 1108 1109 /* Set pScrn->monitor */ 1110 pScrn->monitor = pScrn->confScreen->monitor; 1111 1112 /* 1113 * The first thing we should figure out is the depth, bpp, etc. 1114 * Our preference for depth 24 is 24bpp, so tell it that too. 1115 */ 1116 if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb | 1117 SupportConvert32to24 /*| PreferConvert32to24*/)) { 1118 return FALSE; 1119 } else { 1120 /* Check that the returned depth is one we support */ 1121 switch (pScrn->depth) { 1122 case 8: 1123 if (pScrn->bitsPerPixel != pScrn->depth) { 1124 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1125 "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n", 1126 pScrn->depth, pScrn->bitsPerPixel); 1127 return FALSE; 1128 } 1129 break; 1130 case 15: 1131 case 16: 1132 if (pScrn->bitsPerPixel != 16) { 1133 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1134 "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n", 1135 pScrn->depth, pScrn->bitsPerPixel); 1136 return FALSE; 1137 } 1138 break; 1139 case 24: 1140 if ((pScrn->bitsPerPixel != 24) && (pScrn->bitsPerPixel != 32)) { 1141 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1142 "Given depth (%d)/ fbbpp (%d) is not supported by this driver\n", 1143 pScrn->depth, pScrn->bitsPerPixel); 1144 return FALSE; 1145 } 1146 /* OK */ 1147 break; 1148 default: 1149 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1150 "Given depth (%d) is not supported by this driver\n", 1151 pScrn->depth); 1152 return FALSE; 1153 } 1154 } 1155 1156 xf86PrintDepthBpp(pScrn); 1157 1158 /* Get the depth24 pixmap format */ 1159 if (pScrn->depth == 24 && pix24bpp == 0) 1160 pix24bpp = xf86GetBppFromDepth(pScrn, 24); 1161 1162 /* The vgahw module should be loaded here when needed */ 1163 if (!xf86LoadSubModule(pScrn, "vgahw")) 1164 return FALSE; 1165 1166 xf86LoaderReqSymLists(vgahwSymbols, NULL); 1167 1168 /* 1169 * Allocate a vgaHWRec 1170 */ 1171 if (!vgaHWGetHWRec(pScrn)) 1172 return FALSE; 1173 1174 hwp = VGAHWPTR(pScrn); 1175 vgaHWGetIOBase(hwp); 1176 vgaIOBase = hwp->IOBase; 1177 pTrident->PIOBase = hwp->PIOOffset; 1178 1179 xf86SetOperatingState(resVga, pTrident->pEnt->index, ResUnusedOpr); 1180 1181 /* The ramdac module should be loaded here when needed */ 1182 if (!xf86LoadSubModule(pScrn, "ramdac")) 1183 return FALSE; 1184 1185 xf86LoaderReqSymLists(ramdacSymbols, NULL); 1186 1187 /* 1188 * This must happen after pScrn->display has been set because 1189 * xf86SetWeight references it. 1190 */ 1191 if (pScrn->depth > 8) { 1192 /* The defaults are OK for us */ 1193 rgb zeros = {0, 0, 0}; 1194 1195 if (!xf86SetWeight(pScrn, zeros, zeros)) { 1196 return FALSE; 1197 } else { 1198 /* XXX check that weight returned is supported */ 1199 ; 1200 } 1201 } 1202 1203 if (!xf86SetDefaultVisual(pScrn, -1)) { 1204 return FALSE; 1205 } else { 1206 /* We don't currently support DirectColor at > 8bpp */ 1207 if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { 1208 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" 1209 " (%s) is not supported at depth %d\n", 1210 xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); 1211 return FALSE; 1212 } 1213 } 1214 1215 /* 1216 * The new cmap layer needs this to be initialised. 1217 */ 1218 1219 { 1220 Gamma zeros = {0.0, 0.0, 0.0}; 1221 1222 if (!xf86SetGamma(pScrn, zeros)) { 1223 return FALSE; 1224 } 1225 } 1226 1227 /* Collect all of the relevant option flags (fill in pScrn->options) */ 1228 xf86CollectOptions(pScrn, NULL); 1229 1230 /* Process the options */ 1231 if (!(pTrident->Options = xalloc(sizeof(TRIDENTOptions)))) 1232 return FALSE; 1233 memcpy(pTrident->Options, TRIDENTOptions, sizeof(TRIDENTOptions)); 1234 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pTrident->Options); 1235 1236 /* Set the bits per RGB for 8bpp mode */ 1237 if (pScrn->depth == 8) { 1238 /* XXX This is here just to test options. */ 1239 /* Default to 8 */ 1240 pScrn->rgbBits = 6; 1241#if 0 1242 if (xf86GetOptValInteger(pTrident->Options, OPTION_RGB_BITS, 1243 &pScrn->rgbBits)) { 1244 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n", 1245 pScrn->rgbBits); 1246 } 1247#endif 1248 } 1249 from = X_DEFAULT; 1250 1251 pTrident->useEXA = FALSE; 1252 if ((s = (char *)xf86GetOptValString(pTrident->Options, 1253 OPTION_ACCELMETHOD))) { 1254 if (!xf86NameCmp(s, "EXA")) { 1255 pTrident->useEXA = TRUE; 1256 from = X_CONFIG; 1257 } 1258 else if (!xf86NameCmp(s, "XAA")) { 1259 pTrident->useEXA = FALSE; 1260 from = X_CONFIG; 1261 } 1262 } 1263 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s for acceleration\n", 1264 pTrident->useEXA ? "EXA" : "XAA"); 1265 1266 pTrident->HWCursor = TRUE; 1267 if (xf86ReturnOptValBool(pTrident->Options, OPTION_SW_CURSOR, FALSE)) { 1268 from = X_CONFIG; 1269 pTrident->HWCursor = FALSE; 1270 } 1271 if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOACCEL, FALSE)) { 1272 pTrident->NoAccel = TRUE; 1273 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); 1274 } 1275 if (xf86ReturnOptValBool(pTrident->Options, OPTION_PCI_RETRY, FALSE)) { 1276 pTrident->UsePCIRetry = TRUE; 1277 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n"); 1278 } 1279 pTrident->UsePCIBurst = TRUE; 1280 if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOPCIBURST, FALSE)) { 1281 pTrident->UsePCIBurst = FALSE; 1282 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI Burst disbled\n"); 1283 } 1284 /* Display Size override moved to DDC section */ 1285 if(xf86GetOptValInteger(pTrident->Options, OPTION_VIDEO_KEY, 1286 &(pTrident->videoKey))) { 1287 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n", 1288 pTrident->videoKey); 1289 } else { 1290 pTrident->videoKey = (1 << pScrn->offset.red) | 1291 (1 << pScrn->offset.green) | 1292 (((pScrn->mask.blue >> pScrn->offset.blue) - 1) 1293 << pScrn->offset.blue); 1294 } 1295 if (xf86ReturnOptValBool(pTrident->Options, OPTION_NOMMIO, FALSE)) { 1296 pTrident->NoMMIO = TRUE; 1297 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MMIO Disabled\n"); 1298 } 1299 if (xf86ReturnOptValBool(pTrident->Options, OPTION_MMIO_ONLY, FALSE)) { 1300 if (pTrident->NoMMIO) 1301 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MMIO only cannot be set" 1302 " with NoMMIO\n"); 1303 else { 1304 pTrident->MMIOonly = TRUE; 1305 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MMIO only enabled\n"); 1306 } 1307 } 1308 1309 pTrident->dspOverride = 0; 1310 if ((s = xf86GetOptValString(pTrident->Options, OPTION_DISPLAY))) { 1311 if(!xf86NameCmp(s, "CRT")) { 1312 pTrident->dspOverride = CRT_ACTIVE; 1313 xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD off CRT on\n"); 1314 } else if (!xf86NameCmp(s, "LCD")) { 1315 pTrident->dspOverride = LCD_ACTIVE; 1316 xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD on CRT off\n"); 1317 } else if (!xf86NameCmp(s, "Dual")) { 1318 pTrident->dspOverride = LCD_ACTIVE | CRT_ACTIVE; 1319 xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"LCD on CRT on\n"); 1320 } else 1321 xf86DrvMsg(pScrn->scrnIndex,X_ERROR, 1322 "%s is an unknown display option\n",s); 1323 } 1324 if ((s = xf86GetOptValString(pTrident->Options, OPTION_GB))) { 1325 int brightness = -1; 1326 double gamma = -1.0; 1327 Bool error = FALSE; 1328 int i; 1329 1330 i = sscanf(s,"%lf %i",&gamma,&brightness); 1331 1332 if (i != 2 || brightness == -1 || gamma == -1.0) { 1333 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1334 "Invalid Gamma/Brightness argument: %s\n",s); 1335 error = TRUE; 1336 } else { 1337 if (brightness < 0 || brightness > 128) { 1338 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1339 "brightness out of range [0,128]: %i\n",brightness); 1340 error = TRUE; 1341 } 1342 if (gamma <= 0.0 || gamma > 10.0) { 1343 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1344 "gamma out of range (0,10.0]: %f\n",gamma); 1345 error = TRUE; 1346 } 1347 } 1348 1349 if (!error) { 1350 pTrident->GammaBrightnessOn = TRUE; 1351 pTrident->gamma = gamma; 1352 pTrident->brightness = brightness; 1353 xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"Gamma: %f Brightness: %i\n", 1354 gamma,brightness); 1355 } 1356 } 1357 1358 /* The following is a temporary hack */ 1359 pTrident->FPDelay = 7; /* invalid value */ 1360 if (xf86GetOptValInteger(pTrident->Options, OPTION_FP_DELAY, 1361 &pTrident->FPDelay)) { 1362 if (pTrident->FPDelay < -2 || pTrident->FPDelay > 5) { 1363 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "FPDelay %i out if range " 1364 "(-2 < FPDelay < 5)\n",pTrident->FPDelay); 1365 pTrident->FPDelay = 7; 1366 } else 1367 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "FP Delay set to %i\n", 1368 pTrident->FPDelay); 1369 } 1370 if (xf86ReturnOptValBool(pTrident->Options, OPTION_CYBER_SHADOW, FALSE)) { 1371 pTrident->CyberShadow = TRUE; 1372 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Cyber Shadow enabled\n"); 1373 } 1374 if (xf86ReturnOptValBool(pTrident->Options, OPTION_CYBER_STRETCH, FALSE)) { 1375 pTrident->CyberStretch = TRUE; 1376 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Cyber Stretch enabled\n"); 1377 } 1378 1379 pTrident->MUXThreshold = 90000; /* 90MHz */ 1380 if (xf86GetOptValInteger(pTrident->Options, OPTION_MUX_THRESHOLD, 1381 &pTrident->MUXThreshold)) { 1382 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MUX Threshold set to %d\n", 1383 pTrident->MUXThreshold); 1384 } 1385 pTrident->OverrideHsync = 0; 1386 if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_HSYNC, 1387 &pTrident->OverrideHsync)) { 1388 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Hsync set to %d\n", 1389 pTrident->OverrideHsync); 1390 } 1391 pTrident->OverrideVsync = 0; 1392 if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_VSYNC, 1393 &pTrident->OverrideVsync)) { 1394 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Vsync set to %d\n", 1395 pTrident->OverrideVsync); 1396 } 1397 pTrident->OverrideHsync = 0; 1398 if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_HSYNC, 1399 &pTrident->OverrideHsync)) { 1400 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Hsync set to %d\n", 1401 pTrident->OverrideHsync); 1402 } 1403 pTrident->OverrideVsync = 0; 1404 if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_VSYNC, 1405 &pTrident->OverrideVsync)) { 1406 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Vsync set to %d\n", 1407 pTrident->OverrideVsync); 1408 } 1409 pTrident->OverrideRskew = 0; 1410 if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_RSKEW, 1411 &pTrident->OverrideRskew)) { 1412 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Rskew set to %d\n", 1413 pTrident->OverrideRskew); 1414 } 1415 pTrident->OverrideBskew = 0; 1416 if (xf86GetOptValInteger(pTrident->Options, OPTION_XV_BSKEW, 1417 &pTrident->OverrideBskew)) { 1418 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Xv Bskew set to %d\n", 1419 pTrident->OverrideBskew); 1420 } 1421 if (xf86ReturnOptValBool(pTrident->Options, OPTION_SHADOW_FB, FALSE)) { 1422 if (!pTrident->Linear) 1423 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Ignoring Option SHADOW_FB" 1424 " in non-Linear Mode\n"); 1425 else { 1426 pTrident->ShadowFB = TRUE; 1427 pTrident->NoAccel = TRUE; 1428 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1429 "Using \"Shadow Framebuffer\" - acceleration disabled\n"); 1430 } 1431 } 1432 pTrident->Rotate = 0; 1433 if ((s = xf86GetOptValString(pTrident->Options, OPTION_ROTATE))) { 1434 if (!pTrident->Linear) 1435 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Ignoring Option ROTATE " 1436 "in non-Linear Mode\n"); 1437 else { 1438 if(!xf86NameCmp(s, "CW")) { 1439 /* accel is disabled below for shadowFB */ 1440 pTrident->ShadowFB = TRUE; 1441 pTrident->NoAccel = TRUE; 1442 pTrident->HWCursor = FALSE; 1443 pTrident->Rotate = 1; 1444 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1445 "Rotating screen clockwise - acceleration disabled\n"); 1446 } else if(!xf86NameCmp(s, "CCW")) { 1447 pTrident->ShadowFB = TRUE; 1448 pTrident->NoAccel = TRUE; 1449 pTrident->HWCursor = FALSE; 1450 pTrident->Rotate = -1; 1451 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen" 1452 "counter clockwise - acceleration disabled\n"); 1453 } else { 1454 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid" 1455 "value for Option \"Rotate\"\n", s); 1456 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1457 "Valid options are \"CW\" or \"CCW\"\n"); 1458 } 1459 } 1460 } 1461 1462 pTrident->TVChipset = 0; 1463 if ((s = xf86GetOptValString(pTrident->Options, OPTION_TV_CHIPSET))) { 1464 if(!xf86NameCmp(s, "VT1621")) { 1465 pTrident->TVChipset = 1; 1466 xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"Using VIA VT1621 TV chip\n"); 1467 } else if (!xf86NameCmp(s, "CH7005")) { 1468 pTrident->TVChipset = 2; 1469 xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"Using Chrontel CH7005 TV chip\n"); 1470 } else 1471 xf86DrvMsg(pScrn->scrnIndex,X_ERROR, 1472 "%s is an unknown TV chipset option\n",s); 1473 } 1474 /* Default : NTSC */ 1475 pTrident->TVSignalMode=0; 1476 if (xf86GetOptValInteger(pTrident->Options, OPTION_TV_SIGNALMODE, 1477 &pTrident->TVSignalMode)) { 1478 ErrorF("TV SignalMode set to %d\n",pTrident->TVSignalMode); 1479 } 1480 1481 /* FIXME ACCELERATION */ 1482 if (!UseMMIO) pTrident->NoAccel = TRUE; 1483 1484 if (pTrident->Linear) { 1485 if (pTrident->pEnt->device->MemBase != 0) { 1486 /* 1487 * XXX Should check that the config file value matches one of the 1488 * PCI base address values. 1489 */ 1490 pTrident->FbAddress = pTrident->pEnt->device->MemBase; 1491 from = X_CONFIG; 1492 } else { 1493 if (IsPciCard) 1494 pTrident->FbAddress = pTrident->PciInfo->memBase[0]& 0xFFFFFFF0; 1495 else 1496 pTrident->FbAddress = 0xA0000; 1497 } 1498 1499 xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", 1500 (unsigned long)pTrident->FbAddress); 1501 } 1502 1503 if (UseMMIO) { 1504 if (pTrident->pEnt->device->IOBase != 0) { 1505 /* 1506 * XXX Should check that the config file value matches one of the 1507 * PCI base address values. 1508 */ 1509 pTrident->IOAddress = pTrident->pEnt->device->IOBase; 1510 from = X_CONFIG; 1511 } else { 1512 if (IsPciCard) 1513 pTrident->IOAddress = pTrident->PciInfo->memBase[1]& 0xFFFFC000; 1514 else 1515 /* FIXME - Multihead UNAWARE */ 1516 pTrident->IOAddress = 0xBF000; 1517 } 1518 1519 xf86DrvMsg(pScrn->scrnIndex,X_PROBED,"IO registers at 0x%lX\n", 1520 (unsigned long)pTrident->IOAddress); 1521 } 1522 1523 /* Register the PCI-assigned resources. */ 1524 if (xf86RegisterResources(pTrident->pEnt->index, NULL, ResExclusive)) { 1525 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1526 "xf86RegisterResources() found resource conflicts\n"); 1527 return FALSE; 1528 } 1529 1530 /* Initialize VBE if possible 1531 * Don't move this past MMIO enable!! 1532 * PIO access will be blocked 1533 * when MMIO is turned on! 1534 */ 1535 1536 if (xf86LoadSubModule(pScrn, "vbe")) { 1537 vbeInfoPtr pVbe; 1538 1539 xf86LoaderReqSymLists(vbeSymbols, NULL); 1540 pVbe = VBEInit(NULL,pTrident->pEnt->index); 1541 pMon = vbeDoEDID(pVbe, NULL); 1542#ifdef VBE_INFO 1543 { 1544 VbeInfoBlock* vbeInfoBlockPtr; 1545 if ((vbeInfoBlockPtr = VBEGetVBEInfo(pVbe))) { 1546 pTrident->vbeModes = VBEBuildVbeModeList(pVbe,vbeInfoBlockPtr); 1547 VBEFreeVBEInfo(vbeInfoBlockPtr); 1548 } 1549 } 1550#endif 1551 vbeFree(pVbe); 1552 if (pMon) { 1553 if (!xf86LoadSubModule(pScrn, "ddc")) { 1554 TRIDENTFreeRec(pScrn); 1555 return FALSE; 1556 } else { 1557 xf86LoaderReqSymLists(ddcSymbols, NULL); 1558 xf86SetDDCproperties(pScrn,xf86PrintEDID(pMon)); 1559 ddcLoaded = TRUE; 1560 } 1561 } 1562 1563 } 1564 1565 if (xf86GetOptValBool(pTrident->Options, OPTION_1400_DISPLAY, &tmp_bool)) { 1566 if (tmp_bool) 1567 pTrident->displaySize = 1400; 1568 } else 1569 pTrident->displaySize = TRIDENTLcdDisplaySize(pMon); 1570 1571 if (IsPciCard && UseMMIO) { 1572 if (!TRIDENTMapMem(pScrn)) 1573 return FALSE; 1574 1575 TRIDENTEnableMMIO(pScrn); 1576 } 1577 1578 OUTB(0x3C4, RevisionID); revision = INB(0x3C5); 1579 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Revision is %d\n",revision); 1580 1581 pScrn->progClock = TRUE; 1582 pTrident->EngineOperation = 0x00; 1583 pTrident->IsCyber = FALSE; 1584 pTrident->HasSGRAM = FALSE; 1585 pTrident->NewClockCode = FALSE; 1586 pTrident->MUX = FALSE; 1587 Support24bpp = FALSE; 1588 1589 OUTB(vgaIOBase + 4, InterfaceSel); 1590 1591 switch (pTrident->Chipset) { 1592 case TVGA9000: 1593 case TVGA9000i: 1594 pScrn->progClock = FALSE; 1595 NoClocks = 16; 1596 pTrident->NoMMIO = TRUE; 1597 pTrident->NoAccel = TRUE; 1598 pTrident->HWCursor = FALSE; 1599 chipset = "TVGA9000/9000i"; 1600 ramtype = "Standard DRAM"; 1601 if (pTrident->UsePCIRetry) 1602 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); 1603 pTrident->UsePCIRetry = FALSE; /* Not Supported */ 1604 pTrident->frequency = NTSC; 1605 break; 1606 case TVGA9100B: 1607 pScrn->progClock = FALSE; 1608 NoClocks = 8; 1609 pTrident->NoMMIO = TRUE; 1610 pTrident->NoAccel = TRUE; 1611 pTrident->HWCursor = FALSE; 1612 chipset = "TVGA9100B"; 1613 ramtype = "Standard DRAM"; 1614 if (pTrident->UsePCIRetry) 1615 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); 1616 pTrident->UsePCIRetry = FALSE; /* Not Supported */ 1617 pTrident->frequency = NTSC; 1618 break; 1619 case TVGA8900B: 1620 pScrn->progClock = FALSE; 1621 NoClocks = 8; 1622 pTrident->NoMMIO = TRUE; 1623 pTrident->NoAccel = TRUE; 1624 pTrident->HWCursor = FALSE; 1625 chipset = "TVGA8900B"; 1626 ramtype = "Standard DRAM"; 1627 if (pTrident->UsePCIRetry) 1628 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); 1629 pTrident->UsePCIRetry = FALSE; /* Not Supported */ 1630 pTrident->frequency = NTSC; 1631 break; 1632 case TVGA8900C: 1633 pScrn->progClock = FALSE; 1634 NoClocks = 16; 1635 pTrident->NoMMIO = TRUE; 1636 pTrident->NoAccel = TRUE; 1637 pTrident->HWCursor = FALSE; 1638 chipset = "TVGA8900C"; 1639 ramtype = "Standard DRAM"; 1640 if (pTrident->UsePCIRetry) 1641 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); 1642 pTrident->UsePCIRetry = FALSE; /* Not Supported */ 1643 pTrident->frequency = NTSC; 1644 break; 1645 case TVGA8900D: 1646 pScrn->progClock = FALSE; 1647 NoClocks = 16; 1648 pTrident->NoMMIO = TRUE; 1649 pTrident->NoAccel = TRUE; 1650 pTrident->HWCursor = FALSE; 1651 chipset = "TVGA8900D"; 1652 ramtype = "Standard DRAM"; 1653 if (pTrident->UsePCIRetry) 1654 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); 1655 pTrident->UsePCIRetry = FALSE; /* Not Supported */ 1656 pTrident->frequency = NTSC; 1657 break; 1658 case TVGA9200CXr: 1659 pScrn->progClock = FALSE; 1660 NoClocks = 16; 1661 pTrident->NoMMIO = TRUE; 1662 pTrident->NoAccel = TRUE; 1663 pTrident->HWCursor = FALSE; 1664 chipset = "TVGA9200CXr"; 1665 ramtype = "Standard DRAM"; 1666 if (pTrident->UsePCIRetry) 1667 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); 1668 pTrident->UsePCIRetry = FALSE; /* Not Supported */ 1669 pTrident->frequency = NTSC; 1670 break; 1671 case TGUI9400CXi: 1672 pScrn->progClock = FALSE; 1673 NoClocks = 16; 1674 pTrident->NoMMIO = TRUE; 1675 pTrident->NoAccel = TRUE; 1676 pTrident->HWCursor = FALSE; 1677 chipset = "TVGA9200CXr"; 1678 ramtype = "Standard DRAM"; 1679 if (pTrident->UsePCIRetry) 1680 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); 1681 pTrident->UsePCIRetry = FALSE; /* Not Supported */ 1682 pTrident->frequency = NTSC; 1683 break; 1684 case TGUI9440AGi: 1685 pTrident->ddc1Read = Tridentddc1Read; 1686 pTrident->HWCursor = FALSE; 1687 chipset = "TGUI9440AGi"; 1688 ramtype = "Standard DRAM"; 1689 if (pTrident->UsePCIRetry) 1690 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); 1691 pTrident->UsePCIRetry = FALSE; /* Not Supported */ 1692 pTrident->frequency = NTSC; 1693 break; 1694 case CYBER9320: 1695 pTrident->ddc1Read = Tridentddc1Read; 1696 chipset = "Cyber9320"; 1697 ramtype = "Standard DRAM"; 1698 if (pTrident->UsePCIRetry) 1699 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); 1700 pTrident->UsePCIRetry = FALSE; /* Not Supported */ 1701 break; 1702 /* Trident didn't update the PCI ID's and so we have to detemine 1703 * which chips are right ! Then override pTrident->Chipset to 1704 * correct values */ 1705 case TGUI9660: 1706 pTrident->ddc1Read = Tridentddc1Read; 1707 if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) 1708 ramtype = "EDO Ram"; 1709 if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) 1710 ramtype = "Standard DRAM"; 1711 switch (revision) { 1712 case 0x00: 1713 chipset = "TGUI9660"; 1714 pTrident->Chipset = TGUI9660; 1715 if (pTrident->UsePCIRetry) 1716 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); 1717 pTrident->UsePCIRetry = FALSE; /* Not Supported */ 1718 break; 1719 case 0x01: 1720 chipset = "TGUI9680"; 1721 pTrident->Chipset = TGUI9680; 1722 if (pTrident->UsePCIRetry) 1723 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); 1724 pTrident->UsePCIRetry = FALSE; /* Not Supported */ 1725 break; 1726 case 0x10: 1727 chipset = "ProVidia 9682"; 1728 Support24bpp = TRUE; 1729 pTrident->Chipset = PROVIDIA9682; 1730 break; 1731 case 0x21: 1732 chipset = "ProVidia 9685"; 1733 Support24bpp = TRUE; 1734 pTrident->NewClockCode = TRUE; 1735 pTrident->Chipset = PROVIDIA9685; 1736 break; 1737 case 0x22: 1738 case 0x23: 1739 chipset = "Cyber 9397"; 1740 if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) 1741 ramtype = "EDO Ram"; 1742 if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) 1743 ramtype = "SDRAM"; 1744 if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { 1745 pTrident->HasSGRAM = TRUE; 1746 ramtype = "SGRAM"; 1747 } 1748 pTrident->NewClockCode = TRUE; 1749 pTrident->Chipset = CYBER9397; 1750 pTrident->IsCyber = TRUE; 1751 break; 1752 case 0x2a: 1753 chipset = "Cyber 9397/DVD"; 1754 if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) 1755 ramtype = "EDO Ram"; 1756 if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) 1757 ramtype = "SDRAM"; 1758 if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { 1759 pTrident->HasSGRAM = TRUE; 1760 ramtype = "SGRAM"; 1761 } 1762 pTrident->NewClockCode = TRUE; 1763 pTrident->Chipset = CYBER9397DVD; 1764 pTrident->IsCyber = TRUE; 1765 break; 1766 case 0x30: 1767 case 0x33: 1768 case 0x34: 1769 case 0x35: 1770 case 0xB3: 1771 chipset = "Cyber 9385"; 1772 pTrident->NewClockCode = TRUE; 1773 pTrident->Chipset = CYBER9385; 1774 pTrident->IsCyber = TRUE; 1775 break; 1776 case 0x38: 1777 case 0x3A: 1778 chipset = "Cyber 9385-1"; 1779 pTrident->NewClockCode = TRUE; 1780 pTrident->Chipset = CYBER9385; 1781 pTrident->IsCyber = TRUE; 1782 break; 1783 case 0x40: 1784 case 0x41: 1785 case 0x42: 1786 case 0x43: 1787 chipset = "Cyber 9382"; 1788 pTrident->NewClockCode = TRUE; 1789 pTrident->Chipset = CYBER9382; 1790 pTrident->IsCyber = TRUE; 1791 break; 1792 case 0x4A: 1793 chipset = "Cyber 9388"; 1794 if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) 1795 ramtype = "EDO Ram"; 1796 if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) 1797 ramtype = "SDRAM"; 1798 if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { 1799 pTrident->HasSGRAM = TRUE; 1800 ramtype = "SGRAM"; 1801 } 1802 pTrident->NewClockCode = TRUE; 1803 pTrident->Chipset = CYBER9388; 1804 pTrident->IsCyber = TRUE; 1805 break; 1806 default: 1807 chipset = "Unknown"; 1808 pTrident->Chipset = TGUI9660; 1809 break; 1810 } 1811 break; 1812 case CYBER9388: 1813 pTrident->ddc1Read = Tridentddc1Read; 1814 if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) 1815 ramtype = "EDO Ram"; 1816 if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) 1817 ramtype = "SDRAM"; 1818 if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { 1819 pTrident->HasSGRAM = TRUE; 1820 ramtype = "SGRAM"; 1821 } 1822 pTrident->IsCyber = TRUE; 1823 Support24bpp = TRUE; 1824 chipset = "Cyber 9388"; 1825 pTrident->NewClockCode = TRUE; 1826 break; 1827 case CYBER9397: 1828 pTrident->ddc1Read = Tridentddc1Read; 1829 if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) 1830 ramtype = "EDO Ram"; 1831 if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) 1832 ramtype = "SDRAM"; 1833 if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { 1834 pTrident->HasSGRAM = TRUE; 1835 ramtype = "SGRAM"; 1836 } 1837 pTrident->IsCyber = TRUE; 1838 Support24bpp = TRUE; 1839 chipset = "Cyber 9397"; 1840 pTrident->NewClockCode = TRUE; 1841 break; 1842 case CYBER9397DVD: 1843 pTrident->ddc1Read = Tridentddc1Read; 1844 if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) 1845 ramtype = "EDO Ram"; 1846 if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) 1847 ramtype = "SDRAM"; 1848 if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { 1849 pTrident->HasSGRAM = TRUE; 1850 ramtype = "SGRAM"; 1851 } 1852 pTrident->IsCyber = TRUE; 1853 Support24bpp = TRUE; 1854 chipset = "Cyber 9397/DVD"; 1855 pTrident->NewClockCode = TRUE; 1856 break; 1857 case CYBER9520: 1858 pTrident->ddc1Read = Tridentddc1Read; 1859 if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) 1860 ramtype = "EDO Ram"; 1861 if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) 1862 ramtype = "SDRAM"; 1863 if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { 1864 pTrident->HasSGRAM = TRUE; 1865 ramtype = "SGRAM"; 1866 } 1867 pTrident->IsCyber = TRUE; 1868 Support24bpp = TRUE; 1869 chipset = "Cyber 9520"; 1870 pTrident->NewClockCode = TRUE; 1871 break; 1872 case CYBER9525DVD: 1873 pTrident->ddc1Read = Tridentddc1Read; 1874 if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) 1875 ramtype = "EDO Ram"; 1876 if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) 1877 ramtype = "SDRAM"; 1878 if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { 1879 pTrident->HasSGRAM = TRUE; 1880 ramtype = "SGRAM"; 1881 } 1882 pTrident->IsCyber = TRUE; 1883 Support24bpp = TRUE; 1884 chipset = "Cyber 9525/DVD"; 1885 pTrident->NewClockCode = TRUE; 1886 break; 1887 case CYBERBLADEE4: 1888 pTrident->ddc1Read = Tridentddc1Read; 1889 ramtype = "SDRAM"; 1890 pTrident->IsCyber = TRUE; 1891 Support24bpp = TRUE; 1892 chipset = "CyberBlade e4/128"; 1893 pTrident->NewClockCode = TRUE; 1894 break; 1895 case IMAGE975: 1896 pTrident->ddc1Read = Tridentddc1Read; 1897 if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) 1898 ramtype = "EDO Ram"; 1899 if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) 1900 ramtype = "SDRAM"; 1901 if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { 1902 pTrident->HasSGRAM = TRUE; 1903 ramtype = "SGRAM"; 1904 } 1905 Support24bpp = TRUE; 1906 chipset = "3DImage975"; 1907 pTrident->NewClockCode = TRUE; 1908 break; 1909 case IMAGE985: 1910 pTrident->ddc1Read = Tridentddc1Read; 1911 if ((INB(vgaIOBase + 5) & 0x0C) == 0x04) 1912 ramtype = "EDO Ram"; 1913 if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) 1914 ramtype = "SDRAM"; 1915 if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { 1916 pTrident->HasSGRAM = TRUE; 1917 ramtype = "SGRAM"; 1918 } 1919 Support24bpp = TRUE; 1920 chipset = "3DImage985"; 1921 pTrident->NewClockCode = TRUE; 1922 break; 1923 case BLADE3D: 1924 pTrident->ddc1Read = Tridentddc1Read; 1925 if ((INB(vgaIOBase + 5) & 0x0C) == 0x08) 1926 ramtype = "SDRAM"; 1927 if ((INB(vgaIOBase + 5) & 0x0C) == 0x0C) { 1928 pTrident->HasSGRAM = TRUE; 1929 ramtype = "SGRAM"; 1930 } 1931 Support24bpp = TRUE; 1932 chipset = "Blade3D"; 1933 pTrident->NewClockCode = TRUE; 1934 pTrident->frequency = NTSC; 1935 pTrident->UsePCIRetry = TRUE; /* To avoid lockups */ 1936 break; 1937 case CYBERBLADEI7: 1938 pTrident->ddc1Read = Tridentddc1Read; 1939 ramtype = "SDRAM"; 1940 /* pTrident->IsCyber = TRUE; VIA MVP4 integrated Desktop version */ 1941 Support24bpp = TRUE; 1942 chipset = "CyberBlade/i7/VIA MVP4"; 1943 pTrident->NewClockCode = TRUE; 1944 pTrident->frequency = NTSC; 1945 break; 1946 case CYBERBLADEI7D: 1947 pTrident->ddc1Read = Tridentddc1Read; 1948 ramtype = "SDRAM"; 1949 pTrident->IsCyber = TRUE; 1950 Support24bpp = TRUE; 1951 chipset = "CyberBlade/DSTN/i7"; 1952 pTrident->NewClockCode = TRUE; 1953 pTrident->frequency = NTSC; 1954 break; 1955 case CYBERBLADEI1: 1956 pTrident->ddc1Read = Tridentddc1Read; 1957 ramtype = "SDRAM"; 1958 pTrident->IsCyber = TRUE; 1959 Support24bpp = TRUE; 1960 chipset = "CyberBlade/i1"; 1961 pTrident->NewClockCode = TRUE; 1962 pTrident->frequency = NTSC; 1963 break; 1964 case CYBERBLADEI1D: 1965 pTrident->ddc1Read = Tridentddc1Read; 1966 ramtype = "SDRAM"; 1967 pTrident->IsCyber = TRUE; 1968 Support24bpp = TRUE; 1969 chipset = "CyberBlade/DSTN/i1"; 1970 pTrident->NewClockCode = TRUE; 1971 pTrident->frequency = NTSC; 1972 break; 1973 case CYBERBLADEAI1: 1974 pTrident->ddc1Read = Tridentddc1Read; 1975 ramtype = "SDRAM"; 1976 pTrident->IsCyber = TRUE; 1977 Support24bpp = TRUE; 1978 chipset = "CyberBlade/Ai1"; 1979 pTrident->NewClockCode = TRUE; 1980 pTrident->frequency = NTSC; 1981 break; 1982 case CYBERBLADEAI1D: 1983 pTrident->ddc1Read = Tridentddc1Read; 1984 ramtype = "SDRAM"; 1985 pTrident->IsCyber = TRUE; 1986 Support24bpp = TRUE; 1987 chipset = "CyberBlade/DSTN/Ai1"; 1988 pTrident->NewClockCode = TRUE; 1989 pTrident->frequency = NTSC; 1990 break; 1991 case BLADEXP: /* 0x9910 */ 1992 pTrident->ddc1Read = Tridentddc1Read; 1993 ramtype = "SGRAM"; 1994 pTrident->HasSGRAM = TRUE; 1995 Support24bpp = TRUE; 1996 pTrident->NewClockCode = TRUE; 1997 pTrident->frequency = NTSC; 1998 OUTB(0x3C4, 0x5D); 1999 if (pTrident->PciInfo->subsysVendor != 0x1023) { 2000 chipset = "CyberBladeXP"; 2001 pTrident->IsCyber = TRUE; 2002 } else 2003 if (!(INB(0x3C5) & 0x01)) { 2004 chipset = "BladeXP"; 2005 } else { 2006 CARD8 mem1, mem2; 2007 OUTB(vgaIOBase + 0x04, SPR); 2008 mem1 = INB(vgaIOBase + 5); 2009 OUTB(vgaIOBase + 0x04, 0xC1); 2010 mem2 = INB(vgaIOBase + 5); 2011 if ((mem1 & 0x0e) && (mem2 == 0x11)) { 2012 chipset = "BladeT64"; 2013 } else { 2014 chipset = "BladeT16"; 2015 } 2016 } 2017 break; 2018 case CYBERBLADEXPAI1: 2019 pTrident->ddc1Read = Tridentddc1Read; 2020 ramtype = "SGRAM"; 2021 pTrident->HasSGRAM = TRUE; 2022 pTrident->IsCyber = TRUE; 2023 pTrident->shadowNew = TRUE; 2024 Support24bpp = TRUE; 2025 chipset = "CyberBladeXPAi1"; 2026 pTrident->NewClockCode = TRUE; 2027 pTrident->frequency = NTSC; 2028 break; 2029 case CYBERBLADEXP4: 2030 pTrident->ddc1Read = Tridentddc1Read; 2031 ramtype = "SGRAM"; 2032 pTrident->HasSGRAM = TRUE; 2033 pTrident->IsCyber = TRUE; 2034 pTrident->shadowNew = TRUE; 2035 Support24bpp = TRUE; 2036 chipset = "CyberBladeXP4"; 2037 pTrident->NewClockCode = TRUE; 2038 pTrident->frequency = NTSC; 2039 break; 2040 case XP5: 2041 pTrident->ddc1Read = Tridentddc1Read; 2042 ramtype = "SGRAM"; 2043 pTrident->HasSGRAM = TRUE; 2044 pTrident->IsCyber = TRUE; 2045 pTrident->shadowNew = TRUE; 2046 Support24bpp = TRUE; 2047 chipset = "XP5"; 2048 pTrident->NewClockCode = TRUE; 2049 pTrident->frequency = NTSC; 2050 break; 2051 } 2052 2053 if (!pScrn->progClock) { 2054 pScrn->numClocks = NoClocks; 2055 xf86GetClocks(pScrn, NoClocks, TRIDENTClockSelect, 2056 vgaHWProtectWeak(), 2057 vgaHWBlankScreenWeak(), 2058 vgaIOBase + 0x0A, 0x08, 1, 28322); 2059 from = X_PROBED; 2060 xf86ShowClocks(pScrn, from); 2061 } 2062 2063 if (!chipset) { 2064 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No support for \"%s\"\n", 2065 pScrn->chipset); 2066 if (IsPciCard && UseMMIO) { 2067 TRIDENTDisableMMIO(pScrn); 2068 TRIDENTUnmapMem(pScrn); 2069 } 2070 return FALSE; 2071 } 2072 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Found %s chip\n", chipset); 2073 if (ramtype) 2074 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "RAM type is %s\n", ramtype); 2075 2076 if (pScrn->bitsPerPixel == 24 && !Support24bpp) { 2077 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "No support for 24bpp on this chipset, use -pixmap32.\n"); 2078 if (IsPciCard && UseMMIO) { 2079 TRIDENTDisableMMIO(pScrn); 2080 TRIDENTUnmapMem(pScrn); 2081 } 2082 return FALSE; 2083 } 2084 2085 /* HW bpp matches reported bpp */ 2086 pTrident->HwBpp = pScrn->bitsPerPixel; 2087 2088 /* Due to bugs in the chip, turn it off */ 2089 if (pTrident->Chipset >= CYBERBLADEI7 && pTrident->Chipset <= CYBERBLADEAI1D) 2090 pTrident->HWCursor = FALSE; 2091 2092 from = X_PROBED; 2093 if (pTrident->pEnt->device->videoRam != 0) { 2094 pScrn->videoRam = pTrident->pEnt->device->videoRam; 2095 from = X_CONFIG; 2096 } else { 2097 if (pTrident->Chipset == XP5) { 2098 OUTB(vgaIOBase + 4, 0x60); 2099 videoram = INB(vgaIOBase + 5); 2100 switch (videoram & 0x7) { 2101 case 0x00: 2102 pScrn->videoRam = 65536 /* 131072 */; 2103 break; 2104 case 0x01: 2105 pScrn->videoRam = 65536; 2106 break; 2107 case 0x02: 2108 pScrn->videoRam = 32768; 2109 break; 2110 case 0x03: 2111 pScrn->videoRam = 16384; 2112 break; 2113 case 0x04: 2114 pScrn->videoRam = 8192; 2115 break; 2116 } 2117 } else 2118 if (pTrident->Chipset == CYBER9525DVD) { 2119 pScrn->videoRam = 2560; 2120 } else 2121 { 2122 OUTB(vgaIOBase + 4, SPR); 2123 videoram = INB(vgaIOBase + 5); 2124 if (pTrident->Chipset < TGUI9440AGi) 2125 videorammask = 0x07; 2126 else 2127 videorammask = 0x0F; 2128 switch (videoram & videorammask) { 2129 case 0x01: 2130 pScrn->videoRam = 512; 2131 break; 2132 case 0x02: /* XP */ 2133 pScrn->videoRam = 6144; 2134 break; 2135 case 0x03: 2136 pScrn->videoRam = 1024; 2137 break; 2138 case 0x04: 2139 pScrn->videoRam = 8192; 2140 break; 2141 case 0x06: /* XP */ 2142 pScrn->videoRam = 10240; 2143 break; 2144 case 0x07: 2145 pScrn->videoRam = 2048; 2146 break; 2147 case 0x08: /* XP */ 2148 pScrn->videoRam = 12288; 2149 break; 2150 case 0x0A: /* XP */ 2151 pScrn->videoRam = 14336; 2152 break; 2153 case 0x0C: /* XP */ 2154 pScrn->videoRam = 16384; 2155 break; 2156 case 0x0E: /* XP */ 2157 OUTB(vgaIOBase + 4, 0xC1); 2158 switch (INB(vgaIOBase + 5) & 0x11) { 2159 case 0x00: 2160 pScrn->videoRam = 20480; 2161 break; 2162 case 0x01: 2163 pScrn->videoRam = 24576; 2164 break; 2165 case 0x10: 2166 pScrn->videoRam = 28672; 2167 break; 2168 case 0x11: 2169 pScrn->videoRam = 32768; 2170 break; 2171 } 2172 break; 2173 case 0x0F: 2174 pScrn->videoRam = 4096; 2175 break; 2176 default: 2177 pScrn->videoRam = 1024; 2178 xf86DrvMsg(pScrn->scrnIndex, from, 2179 "Unable to determine VideoRam, defaulting to 1MB\n"); 2180 break; 2181 } 2182 } 2183 } 2184 2185 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 2186 pTrident->HWCursor ? "HW" : "SW"); 2187 2188 xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n", 2189 pScrn->videoRam); 2190 2191 if (pTrident->IsCyber) { 2192 unsigned char mod, dsp, dsp1; 2193 2194 pTrident->lcdMode = 0xff; 2195 2196 OUTB(0x3CE,0x42); 2197 dsp = INB(0x3CF); 2198 OUTB(0x3CE,0x43); 2199 dsp1 = INB(0x3CF); 2200 OUTB(0x3CE,0x52); 2201 mod = INB(0x3CF); 2202 /* 2203 * Only allow display size override if 1280x1024 is detected 2204 * Currently 1400x1050 is supported - which is detected as 2205 * 1280x1024 2206 */ 2207 if (pTrident->displaySize) { 2208 if (((mod >> 4) & 3) == 0) { 2209 for (i = 0; LCD[i].mode != 0xff; i++) { 2210 if (pTrident->displaySize == LCD[i].display_x) 2211 pTrident->lcdMode = LCD[i].mode; 2212 } 2213 xf86DrvMsg(pScrn->scrnIndex, 2214 X_INFO,"%s Panel %ix%i found\n", 2215 (dsp & 0x80) ? "TFT" : 2216 ((dsp1 & 0x20) ? "DSTN" : "STN"), 2217 LCD[i].display_x,LCD[i].display_y); 2218 } else { 2219 xf86DrvMsg(pScrn->scrnIndex,X_WARNING, 2220 "Display size override only for 1280x1024\n"); 2221 pTrident->displaySize = 0; 2222 } 2223 } 2224 2225 if (!pTrident->displaySize) { 2226 for (i = 0; LCD[i].mode != 0xff; i++) { 2227 if (LCD[i].mode == ((mod >> 4) & 3)) { 2228 pTrident->lcdMode = i; 2229 xf86DrvMsg(pScrn->scrnIndex, 2230 X_PROBED,"%s Panel %ix%i found\n", 2231 (dsp & 0x80) ? "TFT" : 2232 ((dsp1 & 0x20) ? "DSTN" : "STN"), 2233 LCD[i].display_x,LCD[i].display_y); 2234 } 2235 } 2236 } 2237 if (pTrident->dspOverride) { 2238 if (pTrident->dspOverride & LCD_ACTIVE) 2239 pTrident->lcdActive = TRUE; 2240 else 2241 pTrident->lcdActive = FALSE; 2242 } else { 2243 OUTB(0x3CE, FPConfig); 2244 pTrident->lcdActive = (INB(0x3CF) & 0x10); 2245 } 2246 } 2247 2248 pTrident->MCLK = 0; 2249 mclk = CalculateMCLK(pScrn); 2250 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Memory Clock is %3.2f MHz\n", mclk); 2251 if (xf86GetOptValFreq(pTrident->Options, OPTION_SETMCLK, OPTUNITS_MHZ, 2252 &real)) { 2253 pTrident->MCLK = (int)(real * 1000.0); 2254 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Setting new Memory Clock to %3.2f MHz\n", 2255 (float)(pTrident->MCLK / 1000)); 2256 } 2257 2258 /* Set the min pixel clock */ 2259 pTrident->MinClock = 12000; /* XXX Guess, need to check this */ 2260 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n", 2261 pTrident->MinClock / 1000); 2262 2263 /* 2264 * If the user has specified ramdac speed in the XF86Config 2265 * file, we respect that setting. 2266 */ 2267 if (pTrident->pEnt->device->dacSpeeds[0]) { 2268 int speed = 0; 2269 2270 switch (pScrn->bitsPerPixel) { 2271 case 8: 2272 speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP8]; 2273 break; 2274 case 16: 2275 speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP16]; 2276 break; 2277 case 24: 2278 speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP24]; 2279 break; 2280 case 32: 2281 speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP32]; 2282 break; 2283 } 2284 if (speed == 0) 2285 pTrident->MaxClock = pTrident->pEnt->device->dacSpeeds[0]; 2286 else 2287 pTrident->MaxClock = speed; 2288 from = X_CONFIG; 2289 } else { 2290 switch (pScrn->bitsPerPixel) { 2291 case 16: 2292 pTrident->MaxClock = ClockLimit16bpp[pTrident->Chipset]; 2293 break; 2294 case 24: 2295 pTrident->MaxClock = ClockLimit24bpp[pTrident->Chipset]; 2296 break; 2297 case 32: 2298 pTrident->MaxClock = ClockLimit32bpp[pTrident->Chipset]; 2299 break; 2300 default: 2301 pTrident->MaxClock = ClockLimit[pTrident->Chipset]; 2302 break; 2303 } 2304 } 2305 xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n", 2306 pTrident->MaxClock / 1000); 2307 2308 /* 2309 * Setup the ClockRanges, which describe what clock ranges are available, 2310 * and what sort of modes they can be used for. 2311 */ 2312 clockRanges = xnfcalloc(sizeof(ClockRange), 1); 2313 clockRanges->next = NULL; 2314 if (!pScrn->progClock) { 2315 if (pScrn->videoRam < 1024) 2316 clockRanges->ClockMulFactor = 2; 2317 if (pScrn->bitsPerPixel == 16) 2318 clockRanges->ClockMulFactor = 2; 2319 } 2320 clockRanges->minClock = pTrident->MinClock; 2321 clockRanges->maxClock = pTrident->MaxClock; 2322 clockRanges->clockIndex = -1; /* programmable */ 2323 clockRanges->interlaceAllowed = TRUE; 2324 clockRanges->doubleScanAllowed = FALSE; /* XXX check this */ 2325 2326 /* 2327 * xf86ValidateModes will check that the mode HTotal and VTotal values 2328 * don't exceed the chipset's limit if pScrn->maxHValue and 2329 * pScrn->maxVValue are set. Since our TRIDENTValidMode() already takes 2330 * care of this, we don't worry about setting them here. 2331 */ 2332 2333 if (pScrn->bitsPerPixel == 24) { 2334 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2335 "Disabling Engine due to 24bpp.\n"); 2336 pTrident->NoAccel = TRUE; 2337 } 2338 2339 /* Select valid modes from those available */ 2340 if (pTrident->NoAccel || Is3Dchip) { 2341 /* 2342 * XXX Assuming min pitch 256, max 4096 2343 * XXX Assuming min height 128, max 4096 2344 */ 2345 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 2346 pScrn->display->modes, clockRanges, 2347 NULL, 256, 4096, 2348 pScrn->bitsPerPixel, 128, 4096, 2349 pScrn->display->virtualX, 2350 pScrn->display->virtualY, 2351 pTrident->FbMapSize, 2352 LOOKUP_BEST_REFRESH); 2353 } else { 2354 /* 2355 * XXX Assuming min height 128, max 2048 2356 */ 2357 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 2358 pScrn->display->modes, clockRanges, 2359 GetAccelPitchValues(pScrn), 0, 0, 2360 pScrn->bitsPerPixel, 128, 2048, 2361 pScrn->display->virtualX, 2362 pScrn->display->virtualY, 2363 pTrident->FbMapSize, 2364 LOOKUP_BEST_REFRESH); 2365 } 2366 2367 if (i == -1) { 2368 if (IsPciCard && UseMMIO) { 2369 TRIDENTDisableMMIO(pScrn); 2370 TRIDENTUnmapMem(pScrn); 2371 } 2372 TRIDENTFreeRec(pScrn); 2373 return FALSE; 2374 } 2375 2376 /* Prune the modes marked as invalid */ 2377 xf86PruneDriverModes(pScrn); 2378 2379 if (i == 0 || pScrn->modes == NULL) { 2380 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); 2381 if (IsPciCard && UseMMIO) { 2382 TRIDENTDisableMMIO(pScrn); 2383 TRIDENTUnmapMem(pScrn); 2384 } 2385 TRIDENTFreeRec(pScrn); 2386 return FALSE; 2387 } 2388 2389 xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); 2390 2391 /* Set the current mode to the first in the list */ 2392 pScrn->currentMode = pScrn->modes; 2393 2394 /* Print the list of modes being used */ 2395 xf86PrintModes(pScrn); 2396 2397 /* Set display resolution */ 2398 xf86SetDpi(pScrn, 0, 0); 2399 2400 /* Load bpp-specific modules */ 2401 switch (pScrn->bitsPerPixel) { 2402 case 8: 2403 pTrident->EngineOperation |= 0x00; 2404 break; 2405 case 16: 2406 pTrident->EngineOperation |= 0x01; 2407 break; 2408 case 24: 2409 pTrident->EngineOperation |= 0x03; 2410 break; 2411 case 32: 2412 pTrident->EngineOperation |= 0x02; 2413 break; 2414 } 2415 2416 if (xf86LoadSubModule(pScrn, "fb") == NULL) { 2417 if (IsPciCard && UseMMIO) { 2418 TRIDENTDisableMMIO(pScrn); 2419 TRIDENTUnmapMem(pScrn); 2420 } 2421 TRIDENTFreeRec(pScrn); 2422 return FALSE; 2423 } 2424 2425 xf86LoaderReqSymLists(fbSymbols, NULL); 2426 2427 if (!xf86LoadSubModule(pScrn, "i2c")) { 2428 if (IsPciCard && UseMMIO) { 2429 TRIDENTDisableMMIO(pScrn); 2430 TRIDENTUnmapMem(pScrn); 2431 } 2432 TRIDENTFreeRec(pScrn); 2433 return FALSE; 2434 } 2435 2436 xf86LoaderReqSymLists(i2cSymbols, NULL); 2437 2438 /* Load shadow if needed */ 2439 if (pTrident->ShadowFB) { 2440 if (!xf86LoadSubModule(pScrn, "shadow")) { 2441 TRIDENTFreeRec(pScrn); 2442 return FALSE; 2443 } 2444 xf86LoaderReqSymLists(shadowSymbols, NULL); 2445 } 2446 2447 /* Load XAA if needed */ 2448 if (!pTrident->NoAccel) { 2449 if (!pTrident->useEXA) { 2450 if (!xf86LoadSubModule(pScrn, "xaa")) { 2451 if (IsPciCard && UseMMIO) { 2452 TRIDENTDisableMMIO(pScrn); 2453 TRIDENTUnmapMem(pScrn); 2454 } 2455 TRIDENTFreeRec(pScrn); 2456 return FALSE; 2457 } 2458 xf86LoaderReqSymLists(xaaSymbols, NULL); 2459 } 2460 2461 if (pTrident->useEXA) { 2462 XF86ModReqInfo req; 2463 int errmaj, errmin; 2464 2465 memset(&req, 0, sizeof(req)); 2466 2467 req.majorversion = 2; 2468 if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req, 2469 &errmaj, &errmin)) 2470 { 2471 LoaderErrorMsg(NULL, "exa", errmaj, errmin); 2472 if (IsPciCard && UseMMIO) { 2473 TRIDENTDisableMMIO(pScrn); 2474 TRIDENTUnmapMem(pScrn); 2475 } 2476 TRIDENTFreeRec(pScrn); 2477 return FALSE; 2478 } 2479 xf86LoaderReqSymLists(exaSymbols, NULL); 2480 } 2481 2482 switch (pScrn->displayWidth * pScrn->bitsPerPixel / 8) { 2483 case 512: 2484 case 8192: 2485 pTrident->EngineOperation |= 0x00; 2486 break; 2487 case 1024: 2488 pTrident->EngineOperation |= 0x04; 2489 break; 2490 case 2048: 2491 pTrident->EngineOperation |= 0x08; 2492 break; 2493 case 4096: 2494 pTrident->EngineOperation |= 0x0C; 2495 break; 2496 } 2497 } 2498 2499 /* Load DDC if needed */ 2500 /* This gives us DDC1 - we should be able to get DDC2B using i2c */ 2501 2502 if (! ddcLoaded) 2503 if (!xf86LoadSubModule(pScrn, "ddc")) { 2504 if (IsPciCard && UseMMIO) { 2505 TRIDENTDisableMMIO(pScrn); 2506 TRIDENTUnmapMem(pScrn); 2507 } 2508 TRIDENTFreeRec(pScrn); 2509 return FALSE; 2510 } 2511 2512 xf86LoaderReqSymLists(ddcSymbols, NULL); 2513 2514 if (IsPciCard && UseMMIO) { 2515 TRIDENTDisableMMIO(pScrn); 2516 TRIDENTUnmapMem(pScrn); 2517 } 2518 2519 pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; 2520 2521 if (pTrident->IsCyber && pTrident->MMIOonly) 2522 pScrn->racIoFlags = 0; 2523 else 2524 pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; 2525 2526 pTrident->FbMapSize = pScrn->videoRam * 1024; 2527 2528 return TRUE; 2529} 2530 2531/* 2532 * Map the framebuffer and MMIO memory. 2533 */ 2534 2535static Bool 2536TRIDENTMapMem(ScrnInfoPtr pScrn) 2537{ 2538 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 2539 vgaHWPtr hwp = VGAHWPTR(pScrn); 2540 int mapsize = 0x10000; 2541 2542 if (Is3Dchip) mapsize = 0x20000; 2543 2544 if (IsPciCard && UseMMIO) 2545 pTrident->IOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, 2546 pTrident->PciTag, pTrident->IOAddress, mapsize); 2547 else { 2548 pTrident->IOBase = xf86MapDomainMemory(pScrn->scrnIndex, VIDMEM_MMIO, 2549 pTrident->PciTag, pTrident->IOAddress, 0x1000); 2550 pTrident->IOBase += 0xF00; 2551 } 2552 2553 if (pTrident->IOBase == NULL) 2554 return FALSE; 2555 2556 if (pTrident->Linear) { 2557 if (pTrident->FbMapSize != 0) { 2558 pTrident->FbBase = xf86MapPciMem(pScrn->scrnIndex, 2559 VIDMEM_FRAMEBUFFER, 2560 pTrident->PciTag, 2561 (unsigned long)pTrident->FbAddress, 2562 pTrident->FbMapSize); 2563 if (pTrident->FbBase == NULL) 2564 return FALSE; 2565 } 2566 } 2567 else 2568 pTrident->FbBase = hwp->Base; 2569 2570 return TRUE; 2571} 2572 2573/* 2574 * Unmap the framebuffer and MMIO memory. 2575 */ 2576 2577static Bool 2578TRIDENTUnmapMem(ScrnInfoPtr pScrn) 2579{ 2580 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 2581 int mapsize = 0x10000; 2582 2583 if (Is3Dchip) mapsize = 0x20000; 2584 2585 /* 2586 * Unmap IO registers to virtual address space 2587 */ 2588 if (IsPciCard && UseMMIO) 2589 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->IOBase, mapsize); 2590 else { 2591 pTrident->IOBase -= 0xF00; 2592 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->IOBase, 0x1000); 2593 } 2594 pTrident->IOBase = NULL; 2595 2596 if (pTrident->Linear) { 2597 if (pTrident->FbMapSize != 0) { 2598 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->FbBase, 2599 pTrident->FbMapSize); 2600 pTrident->FbBase = NULL; 2601 } 2602 } 2603 2604 return TRUE; 2605} 2606 2607 2608/* 2609 * This function saves the video state. 2610 */ 2611static void 2612TRIDENTSave(ScrnInfoPtr pScrn) 2613{ 2614 TRIDENTPtr pTrident; 2615 vgaRegPtr vgaReg; 2616 TRIDENTRegPtr tridentReg; 2617 2618 pTrident = TRIDENTPTR(pScrn); 2619 vgaReg = &VGAHWPTR(pScrn)->SavedReg; 2620 tridentReg = &pTrident->SavedReg; 2621 2622 vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP | 2623 (IsPrimaryCard ? VGA_SR_FONTS : 0)); 2624 2625 if (pScrn->progClock) 2626 TridentSave(pScrn, tridentReg); 2627 else 2628 TVGASave(pScrn, tridentReg); 2629 2630 if (pTrident->TVChipset != 0) 2631 VIA_SaveTVDepentVGAReg(pScrn); 2632} 2633 2634 2635/* 2636 * Initialise a new mode. This is currently still using the old 2637 * "initialise struct, restore/write struct to HW" model. That could 2638 * be changed. 2639 */ 2640 2641static Bool 2642TRIDENTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 2643{ 2644 vgaHWPtr hwp = VGAHWPTR(pScrn); 2645 vgaRegPtr vgaReg; 2646 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 2647 TRIDENTRegPtr tridentReg; 2648 2649 WAITFORVSYNC; 2650 2651 TridentFindClock(pScrn,mode->Clock); 2652 2653 switch (pTrident->Chipset) { 2654 case TGUI9660: 2655 case TGUI9680: 2656 case PROVIDIA9682: 2657 case PROVIDIA9685: 2658 case IMAGE975: 2659 case IMAGE985: 2660 case BLADE3D: 2661 case CYBERBLADEI7: 2662 case CYBERBLADEI7D: 2663 case CYBERBLADEI1: 2664 case CYBERBLADEI1D: 2665 case CYBERBLADEAI1: 2666 case CYBERBLADEAI1D: 2667 case CYBER9520: 2668 case CYBER9525DVD: 2669 case CYBERBLADEE4: 2670 case CYBER9397: 2671 case CYBER9397DVD: 2672 case BLADEXP: 2673 case CYBERBLADEXPAI1: 2674 case CYBERBLADEXP4: 2675 case XP5: 2676 /* Get ready for MUX mode */ 2677 if (pTrident->MUX && 2678 pScrn->bitsPerPixel == 8 && 2679 !mode->CrtcHAdjusted) { 2680 ErrorF("BARF\n"); 2681 mode->CrtcHDisplay >>= 1; 2682 mode->CrtcHSyncStart >>= 1; 2683 mode->CrtcHSyncEnd >>= 1; 2684 mode->CrtcHBlankStart >>= 1; 2685 mode->CrtcHBlankEnd >>= 1; 2686 mode->CrtcHTotal >>= 1; 2687 mode->CrtcHAdjusted = TRUE; 2688 } 2689 break; 2690 default: 2691 if (pScrn->videoRam < 1024 && 2692 !mode->CrtcHAdjusted) { 2693 mode->CrtcHDisplay <<= 1; 2694 mode->CrtcHSyncStart <<= 1; 2695 mode->CrtcHSyncEnd <<= 1; 2696 mode->CrtcHBlankStart <<= 1; 2697 mode->CrtcHBlankEnd <<= 1; 2698 mode->CrtcHTotal <<= 1; 2699 mode->CrtcHAdjusted = TRUE; 2700 } 2701 break; 2702 } 2703 2704 vgaHWUnlock(hwp); 2705 /* Initialise the ModeReg values */ 2706 if (!vgaHWInit(pScrn, mode)) 2707 return FALSE; 2708 2709 pScrn->vtSema = TRUE; 2710 /* 2711 * We used to do this at a later time. 2712 * Now since READOUT isn't defined any more 2713 * we do it here. 2714 * The original NOTE read: 2715 * TridentInit() has to modify registers 2716 * that have already been set by vgaHWRestore(). 2717 * So we call it _after_ vgaHWRestore() has 2718 * programmed these registers. 2719 */ 2720 if (pScrn->progClock) { 2721 if (!TridentInit(pScrn, mode)) 2722 return FALSE; 2723 } else { 2724 if (!TVGAInit(pScrn, mode)) 2725 return FALSE; 2726 } 2727 2728 /* Program the registers */ 2729 vgaHWProtect(pScrn, TRUE); 2730 vgaReg = &hwp->ModeReg; 2731 tridentReg = &pTrident->ModeReg; 2732 2733 vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); 2734 if (pScrn->progClock) 2735 TridentRestore(pScrn, tridentReg); 2736 else 2737 TVGARestore(pScrn, tridentReg); 2738 2739 vgaHWProtect(pScrn, FALSE); 2740 2741 if (xf86IsPc98()) 2742 PC98TRIDENTEnable(pScrn); 2743 2744 if (pTrident->TVChipset != 0) 2745 VIA_TVInit(pScrn); 2746 2747 return TRUE; 2748} 2749 2750/* 2751 * Restore the initial (text) mode. 2752 */ 2753static void 2754TRIDENTRestore(ScrnInfoPtr pScrn) 2755{ 2756 vgaHWPtr hwp; 2757 vgaRegPtr vgaReg; 2758 TRIDENTPtr pTrident; 2759 TRIDENTRegPtr tridentReg; 2760 2761 hwp = VGAHWPTR(pScrn); 2762 pTrident = TRIDENTPTR(pScrn); 2763 vgaReg = &hwp->SavedReg; 2764 tridentReg = &pTrident->SavedReg; 2765 2766 vgaHWProtect(pScrn, TRUE); 2767 2768 if (pScrn->progClock) 2769 TridentRestore(pScrn, tridentReg); 2770 else 2771 TVGARestore(pScrn, tridentReg); 2772 2773 vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP | 2774 (IsPrimaryCard ? VGA_SR_FONTS : 0)); 2775 2776 if (pTrident->TVChipset != 0) 2777 VIA_RestoreTVDependVGAReg(pScrn); 2778 2779 vgaHWProtect(pScrn, FALSE); 2780} 2781 2782 2783/* Mandatory */ 2784 2785/* This gets called at the start of each server generation */ 2786 2787static Bool 2788TRIDENTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 2789{ 2790 /* The vgaHW references will disappear one day */ 2791 ScrnInfoPtr pScrn; 2792 vgaHWPtr hwp; 2793 TRIDENTPtr pTrident; 2794 int ret; 2795 VisualPtr visual; 2796 unsigned char *FBStart; 2797 int width, height, displayWidth; 2798 2799 /* 2800 * First get the ScrnInfoRec 2801 */ 2802 pScrn = xf86Screens[pScreen->myNum]; 2803 pTrident = TRIDENTPTR(pScrn); 2804 2805 if (IsPrimaryCard) { 2806 if (!vgaHWMapMem(pScrn)) 2807 return FALSE; 2808 } 2809 2810 /* Map the TRIDENT memory and MMIO areas */ 2811 if (!TRIDENTMapMem(pScrn)) 2812 return FALSE; 2813 2814 if (!xf86IsPc98()) { 2815#ifdef VBE_INFO 2816 if (pTrident->vbeModes) { 2817 pTrident->pVbe = VBEInit(NULL,pTrident->pEnt->index); 2818 pTrident->Int10 = pTrident->pVbe->pInt10; 2819 } else 2820#endif 2821 { 2822 if (xf86LoadSubModule(pScrn, "int10")) { 2823 xf86LoaderReqSymLists(int10Symbols, NULL); 2824 xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Initializing int10\n"); 2825 pTrident->Int10 = xf86InitInt10(pTrident->pEnt->index); 2826 } 2827 } 2828 } 2829 2830 hwp = VGAHWPTR(pScrn); 2831 2832 if (IsPciCard && UseMMIO) { 2833 TRIDENTEnableMMIO(pScrn); 2834 2835 /* Initialize the MMIO vgahw functions */ 2836 vgaHWSetMmioFuncs(hwp, pTrident->IOBase, 0); 2837 } 2838 2839 /* Save the current state */ 2840 TRIDENTSave(pScrn); 2841 2842 /* 2843 * Some Trident chip on PC-9821 needs setup, 2844 * because VGA chip is not initialized by VGA BIOS. 2845 */ 2846 if (IsPciCard && xf86IsPc98()) { 2847 PC98TRIDENTInit(pScrn); 2848 } else tridentSetModeBIOS(pScrn,pScrn->currentMode); 2849 2850 /* Initialise the first mode */ 2851 if (!TRIDENTModeInit(pScrn, pScrn->currentMode)) 2852 return FALSE; 2853 2854 /* Darken the screen for aesthetic reasons and set the viewport */ 2855 TRIDENTSaveScreen(pScreen, SCREEN_SAVER_ON); 2856 TRIDENTAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 2857 2858 /* 2859 * The next step is to setup the screen's visuals, and initialise the 2860 * framebuffer code. In cases where the framebuffer's default 2861 * choices for things like visual layouts and bits per RGB are OK, 2862 * this may be as simple as calling the framebuffer's ScreenInit() 2863 * function. If not, the visuals will need to be setup before calling 2864 * a fb ScreenInit() function and fixed up after. 2865 * 2866 * For most PC hardware at depths >= 8, the defaults that fb uses 2867 * are not appropriate. In this driver, we fixup the visuals after. 2868 */ 2869 2870 /* 2871 * Reset visual list. 2872 */ 2873 miClearVisualTypes(); 2874 2875 /* Setup the visuals we support. */ 2876 2877 if (!miSetVisualTypes(pScrn->depth, 2878 miGetDefaultVisualMask(pScrn->depth), 2879 pScrn->rgbBits, pScrn->defaultVisual)) { 2880 if (pTrident->pVbe) 2881 vbeFree(pTrident->pVbe); 2882 else 2883 xf86FreeInt10(pTrident->Int10); 2884 return FALSE; 2885 } 2886 2887 miSetPixmapDepths (); 2888 2889 /* FIXME - we don't do shadowfb for < 4 */ 2890 displayWidth = pScrn->displayWidth; 2891 if (pTrident->Rotate) { 2892 height = pScrn->virtualX; 2893 width = pScrn->virtualY; 2894 } else { 2895 width = pScrn->virtualX; 2896 height = pScrn->virtualY; 2897 } 2898 2899 if(pTrident->ShadowFB) { 2900 pTrident->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); 2901 pTrident->ShadowPtr = xalloc(pTrident->ShadowPitch * height); 2902 displayWidth = pTrident->ShadowPitch / (pScrn->bitsPerPixel >> 3); 2903 FBStart = pTrident->ShadowPtr; 2904 } else { 2905 pTrident->ShadowFB = FALSE; 2906 pTrident->ShadowPtr = NULL; 2907 FBStart = pTrident->FbBase; 2908 } 2909 2910 /* 2911 * Call the framebuffer layer's ScreenInit function, and fill in other 2912 * pScreen fields. 2913 */ 2914 2915 switch (pScrn->bitsPerPixel) { 2916 case 8: 2917 case 16: 2918 case 24: 2919 case 32: 2920 ret = fbScreenInit(pScreen, FBStart, width, 2921 height, pScrn->xDpi, pScrn->yDpi, 2922 displayWidth, pScrn->bitsPerPixel); 2923 2924 break; 2925 default: 2926 xf86DrvMsg(scrnIndex, X_ERROR, 2927 "Internal error: invalid bpp (%d) in TRIDENTScrnInit\n", 2928 pScrn->bitsPerPixel); 2929 ret = FALSE; 2930 break; 2931 } 2932 if (!ret) { 2933 if (pTrident->pVbe) 2934 vbeFree(pTrident->pVbe); 2935 else 2936 xf86FreeInt10(pTrident->Int10); 2937 return FALSE; 2938 } 2939 if (pScrn->bitsPerPixel > 8) { 2940 /* Fixup RGB ordering */ 2941 visual = pScreen->visuals + pScreen->numVisuals; 2942 while (--visual >= pScreen->visuals) { 2943 if ((visual->class | DynamicClass) == DirectColor) { 2944 visual->offsetRed = pScrn->offset.red; 2945 visual->offsetGreen = pScrn->offset.green; 2946 visual->offsetBlue = pScrn->offset.blue; 2947 visual->redMask = pScrn->mask.red; 2948 visual->greenMask = pScrn->mask.green; 2949 visual->blueMask = pScrn->mask.blue; 2950 } 2951 } 2952 } 2953 2954 /* must be after RGB ordering fixed */ 2955 fbPictureInit (pScreen, 0, 0); 2956 2957 xf86SetBlackWhitePixels(pScreen); 2958 2959 pTrident->BlockHandler = pScreen->BlockHandler; 2960 pScreen->BlockHandler = TRIDENTBlockHandler; 2961 2962 if (!pTrident->ShadowFB) 2963 TRIDENTDGAInit(pScreen); 2964 2965 if (!pTrident->Linear) { 2966 miBankInfoPtr pBankInfo; 2967 2968 /* Setup the vga banking variables */ 2969 pBankInfo = xnfcalloc(sizeof(miBankInfoRec),1); 2970 if (pBankInfo == NULL) { 2971 if (pTrident->pVbe) 2972 vbeFree(pTrident->pVbe); 2973 else 2974 xf86FreeInt10(pTrident->Int10); 2975 return FALSE; 2976 } 2977 pBankInfo->pBankA = pTrident->FbBase; 2978 pBankInfo->pBankB = pTrident->FbBase; 2979 pBankInfo->BankSize = 0x10000; 2980 pBankInfo->nBankDepth = (pScrn->depth == 4) ? 1 : pScrn->depth; 2981 2982 pBankInfo->SetSourceBank = 2983 (miBankProcPtr)TVGA8900SetRead; 2984 pBankInfo->SetDestinationBank = 2985 (miBankProcPtr)TVGA8900SetWrite; 2986 pBankInfo->SetSourceAndDestinationBanks = 2987 (miBankProcPtr)TVGA8900SetReadWrite; 2988 if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY, 2989 pScrn->displayWidth, pBankInfo)) { 2990 xfree(pBankInfo); 2991 pBankInfo = NULL; 2992 if (pTrident->pVbe) 2993 vbeFree(pTrident->pVbe); 2994 else 2995 xf86FreeInt10(pTrident->Int10); 2996 return FALSE; 2997 } 2998 } 2999 3000 { 3001 BoxRec AvailFBArea; 3002 3003 AvailFBArea.x1 = 0; 3004 AvailFBArea.y1 = 0; 3005 AvailFBArea.x2 = pScrn->displayWidth; 3006 AvailFBArea.y2 = pTrident->FbMapSize / (pScrn->displayWidth * 3007 pScrn->bitsPerPixel / 8); 3008 3009 if (AvailFBArea.y2 > 2047) AvailFBArea.y2 = 2047; 3010 3011 if (xf86InitFBManager(pScreen, &AvailFBArea)) { 3012 int cpp = pScrn->bitsPerPixel / 8; 3013 int area = AvailFBArea.y2 * pScrn->displayWidth; 3014 int areaoffset = area * cpp; 3015 3016 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 3017 "Using %i scanlines of offscreen memory for area's \n", 3018 AvailFBArea.y2 - pScrn->virtualY); 3019 3020 if (xf86InitFBManagerLinear(pScreen, area, ((pTrident->FbMapSize/cpp) - area))) { 3021 xf86DrvMsg(scrnIndex, X_INFO, 3022 "Using %ld bytes of offscreen memory for linear (offset=0x%x)\n", (pTrident->FbMapSize - areaoffset), areaoffset); 3023 } 3024 } 3025 } 3026 3027 if (Is3Dchip) { 3028 if ((pTrident->Chipset == CYBERBLADEI7) || 3029 (pTrident->Chipset == CYBERBLADEI7D) || 3030 (pTrident->Chipset == CYBERBLADEI1) || 3031 (pTrident->Chipset == CYBERBLADEI1D) || 3032 (pTrident->Chipset == CYBERBLADEAI1) || 3033 (pTrident->Chipset == CYBERBLADEAI1D) || 3034 (pTrident->Chipset == CYBERBLADEE4) || 3035 (pTrident->Chipset == BLADE3D)) { 3036 if (pTrident->useEXA) 3037 BladeExaInit(pScreen); 3038 else 3039 BladeXaaInit(pScreen); 3040 } else 3041 if ((pTrident->Chipset == CYBERBLADEXP4) || 3042 (pTrident->Chipset == XP5)) { 3043 if (pTrident->useEXA) 3044 XP4ExaInit(pScreen); 3045 else 3046 XP4XaaInit(pScreen); 3047 } else 3048 if ((pTrident->Chipset == BLADEXP) || 3049 (pTrident->Chipset == CYBERBLADEXPAI1)) { 3050 XPAccelInit(pScreen); 3051 } else { 3052 ImageAccelInit(pScreen); 3053 } 3054 } else { 3055 TridentAccelInit(pScreen); 3056 } 3057 3058 miInitializeBackingStore(pScreen); 3059 xf86SetBackingStore(pScreen); 3060 3061 /* Initialise cursor functions */ 3062 miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); 3063 3064 if (pTrident->HWCursor) { 3065 xf86SetSilkenMouse(pScreen); 3066 TridentHWCursorInit(pScreen); 3067 } 3068 3069 /* Initialise default colourmap */ 3070 if (!miCreateDefColormap(pScreen)) { 3071 if (pTrident->pVbe) 3072 vbeFree(pTrident->pVbe); 3073 else 3074 xf86FreeInt10(pTrident->Int10); 3075 return FALSE; 3076 } 3077 if(!xf86HandleColormaps(pScreen, 256, 6, TridentLoadPalette, 3078 TridentSetOverscan, CMAP_RELOAD_ON_MODE_SWITCH|CMAP_PALETTED_TRUECOLOR)) { 3079 if (pTrident->pVbe) 3080 vbeFree(pTrident->pVbe); 3081 else 3082 xf86FreeInt10(pTrident->Int10); 3083 return FALSE; 3084 } 3085 if(pTrident->ShadowFB) { 3086 if(pTrident->Rotate) { 3087 if (!pTrident->PointerMoved) { 3088 pTrident->PointerMoved = pScrn->PointerMoved; 3089 pScrn->PointerMoved = TRIDENTPointerMoved; 3090 } 3091 switch (pScrn->bitsPerPixel) { 3092 case 8: pTrident->RefreshArea = TRIDENTRefreshArea8; break; 3093 case 16: pTrident->RefreshArea = TRIDENTRefreshArea16; break; 3094 case 24: pTrident->RefreshArea = TRIDENTRefreshArea24; break; 3095 case 32: pTrident->RefreshArea = TRIDENTRefreshArea32; break; 3096 } 3097 } else { 3098 pTrident->RefreshArea = TRIDENTRefreshArea; 3099 } 3100 shadowInit (pScreen, TRIDENTShadowUpdate, 0); 3101 } 3102 3103 xf86DPMSInit(pScreen, (DPMSSetProcPtr)TRIDENTDisplayPowerManagementSet, 0); 3104 3105 pScrn->memPhysBase = pTrident->FbAddress; 3106 pScrn->fbOffset = 0; 3107 3108 if (pTrident->Chipset >= TGUI9660) 3109 TRIDENTInitVideo(pScreen); 3110 3111 pTrident->CloseScreen = pScreen->CloseScreen; 3112 pScreen->CloseScreen = TRIDENTCloseScreen; 3113 pScreen->SaveScreen = TRIDENTSaveScreen; 3114 3115 /* Report any unused options (only for the first generation) */ 3116 if (serverGeneration == 1) { 3117 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 3118 } 3119 3120#if 0 3121 TRIDENTI2CInit(pScreen); 3122 3123 xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex,pTrident->DDC)); 3124#endif 3125 3126 return TRUE; 3127} 3128 3129/* Usually mandatory */ 3130Bool 3131TRIDENTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 3132{ 3133 return TRIDENTModeInit(xf86Screens[scrnIndex], mode); 3134} 3135 3136 3137/* 3138 * This function is used to initialize the Start Address - the first 3139 * displayed location in the video memory. 3140 */ 3141/* Usually mandatory */ 3142void 3143TRIDENTAdjustFrame(int scrnIndex, int x, int y, int flags) 3144{ 3145 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 3146 TRIDENTPtr pTrident; 3147 int base = y * pScrn->displayWidth + x; 3148 int vgaIOBase; 3149 CARD8 temp; 3150 3151 pTrident = TRIDENTPTR(pScrn); 3152 vgaIOBase = VGAHWPTR(pScrn)->IOBase; 3153 3154 switch (pScrn->bitsPerPixel) { 3155 case 8: 3156 if (pScrn->progClock) 3157 base = (base & 0xFFFFFFF8) >> 2; 3158 else 3159 base = (base & 0xFFFFFFF8) >> 3; 3160 break; 3161 case 16: 3162 base >>= 1; 3163 break; 3164 case 24: 3165 base = (((base + 1) & ~0x03) * 3) >> 2; 3166 break; 3167 case 32: 3168 break; 3169 } 3170 3171 /* CRT bits 0-15 */ 3172 OUTW(vgaIOBase + 4, (base & 0x00FF00) | 0x0C); 3173 OUTW(vgaIOBase + 4, ((base & 0x00FF) << 8) | 0x0D); 3174 /* CRT bit 16 */ 3175 OUTB(vgaIOBase + 4, CRTCModuleTest); temp = INB(vgaIOBase + 5) & 0xDF; 3176 OUTB(vgaIOBase + 5, temp | ((base & 0x10000) >> 11)); 3177 /* CRT bit 17-19 */ 3178 OUTB(vgaIOBase + 4, CRTHiOrd); temp = INB(vgaIOBase + 5) & 0xF8; 3179 OUTB(vgaIOBase + 5, temp | ((base & 0xE0000) >> 17)); 3180} 3181 3182 3183/* 3184 * This is called when VT switching back to the X server. Its job is 3185 * to reinitialise the video mode. 3186 */ 3187 3188/* Mandatory */ 3189static Bool 3190TRIDENTEnterVT(int scrnIndex, int flags) 3191{ 3192 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 3193 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 3194 3195 if (IsPciCard && UseMMIO) TRIDENTEnableMMIO(pScrn); 3196 3197 /* Should we re-save the text mode on each VT enter? */ 3198 if (!TRIDENTModeInit(pScrn, pScrn->currentMode)) 3199 return FALSE; 3200 3201 if (pTrident->InitializeAccelerator) 3202 pTrident->InitializeAccelerator(pScrn); 3203 3204 return TRUE; 3205} 3206 3207 3208/* 3209 * This is called when VT switching away from the X server. Its job is 3210 * to restore the previous (text) mode. 3211 * 3212 * We may wish to remap video/MMIO memory too. 3213 */ 3214 3215/* Mandatory */ 3216static void 3217TRIDENTLeaveVT(int scrnIndex, int flags) 3218{ 3219 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 3220 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 3221 vgaHWPtr hwp = VGAHWPTR(pScrn); 3222 3223 if (!pTrident->NoAccel && !pTrident->useEXA) 3224 pTrident->AccelInfoRec->Sync(pScrn); 3225 else if (!pTrident->NoAccel && pTrident->useEXA) 3226 pTrident->EXADriverPtr->WaitMarker(pScrn->pScreen, 0); 3227 3228 TRIDENTRestore(pScrn); 3229 vgaHWLock(hwp); 3230 3231 if (xf86IsPc98()) 3232 PC98TRIDENTDisable(pScrn); 3233 3234 if (IsPciCard && UseMMIO) TRIDENTDisableMMIO(pScrn); 3235} 3236 3237 3238/* 3239 * This is called at the end of each server generation. It restores the 3240 * original (text) mode. It should really also unmap the video memory too. 3241 */ 3242 3243/* Mandatory */ 3244static Bool 3245TRIDENTCloseScreen(int scrnIndex, ScreenPtr pScreen) 3246{ 3247 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 3248 vgaHWPtr hwp = VGAHWPTR(pScrn); 3249 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 3250 3251 if (pScrn->vtSema) { 3252 if (!pTrident->NoAccel && !pTrident->useEXA) 3253 pTrident->AccelInfoRec->Sync(pScrn); 3254 else if (!pTrident->NoAccel && pTrident->useEXA) 3255 pTrident->EXADriverPtr->WaitMarker(pScreen, 0); 3256 3257 if (xf86IsPc98()) 3258 PC98TRIDENTDisable(pScrn); 3259 3260 TRIDENTRestore(pScrn); 3261 vgaHWLock(hwp); 3262 if (IsPciCard && UseMMIO) TRIDENTDisableMMIO(pScrn); 3263 TRIDENTUnmapMem(pScrn); 3264 } 3265 if (pTrident->AccelInfoRec) 3266 XAADestroyInfoRec(pTrident->AccelInfoRec); 3267 if (pTrident->EXADriverPtr) { 3268 exaDriverFini(pScreen); 3269 xfree(pTrident->EXADriverPtr); 3270 pTrident->EXADriverPtr = NULL; 3271 } 3272 if (pTrident->CursorInfoRec) 3273 xf86DestroyCursorInfoRec(pTrident->CursorInfoRec); 3274 if (pTrident->ShadowPtr) 3275 xfree(pTrident->ShadowPtr); 3276 if (pTrident->DGAModes) 3277 xfree(pTrident->DGAModes); 3278 pScrn->vtSema = FALSE; 3279 3280 if(pTrident->BlockHandler) 3281 pScreen->BlockHandler = pTrident->BlockHandler; 3282 3283 if (pTrident->pVbe) 3284 vbeFree(pTrident->pVbe); 3285 else 3286 xf86FreeInt10(pTrident->Int10); 3287 pScreen->CloseScreen = pTrident->CloseScreen; 3288 return (*pScreen->CloseScreen)(scrnIndex, pScreen); 3289} 3290 3291 3292/* Free up any per-generation data structures */ 3293 3294/* Optional */ 3295static void 3296TRIDENTFreeScreen(int scrnIndex, int flags) 3297{ 3298 if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) 3299 vgaHWFreeHWRec(xf86Screens[scrnIndex]); 3300 TRIDENTFreeRec(xf86Screens[scrnIndex]); 3301} 3302 3303 3304/* Checks if a mode is suitable for the selected chipset. */ 3305 3306/* Optional */ 3307static ModeStatus 3308TRIDENTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 3309{ 3310 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 3311 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 3312 3313 if (pTrident->lcdActive && (pTrident->lcdMode != 0xff)){ 3314 if (((mode->HDisplay > LCD[pTrident->lcdMode].display_x) 3315 || (mode->VDisplay > LCD[pTrident->lcdMode].display_y))) { 3316 xf86DrvMsg(scrnIndex,X_INFO, "Removing mode (%dx%d) " 3317 "larger than the LCD panel (%dx%d)\n", 3318 mode->HDisplay, 3319 mode->VDisplay, 3320 LCD[pTrident->lcdMode].display_x, 3321 LCD[pTrident->lcdMode].display_y); 3322 return(MODE_BAD); 3323 } 3324 if (((float)mode->HDisplay/(float)mode->VDisplay) > 2.0) { 3325 xf86DrvMsg(scrnIndex,X_INFO, "Removing mode (%dx%d) " 3326 "unusual aspect ratio\n", 3327 mode->HDisplay, 3328 mode->VDisplay); 3329 return(MODE_BAD); 3330 } 3331 } 3332 return (MODE_OK); 3333} 3334 3335/* Do screen blanking */ 3336 3337/* Mandatory */ 3338static Bool 3339TRIDENTSaveScreen(ScreenPtr pScreen, int mode) 3340{ 3341 return vgaHWSaveScreen(pScreen, mode); 3342} 3343 3344static void 3345TRIDENTEnableMMIO(ScrnInfoPtr pScrn) 3346{ 3347 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 3348 IOADDRESS vgaIOBase = pTrident->PIOBase + VGAHWPTR(pScrn)->IOBase; 3349 CARD8 temp = 0, protect = 0; 3350 3351 /* 3352 * Skip MMIO Enable in PC-9821 PCI Trident Card!! 3353 * Because of lack of non PCI VGA port 3354 */ 3355 if (IsPciCard && xf86IsPc98()) 3356 return; 3357 3358 /* Goto New Mode */ 3359 outb(pTrident->PIOBase + 0x3C4, 0x0B); 3360 inb(pTrident->PIOBase + 0x3C5); 3361 3362 /* Unprotect registers */ 3363 if (pTrident->Chipset > PROVIDIA9685) { 3364 outb(pTrident->PIOBase + 0x3C4, Protection); 3365 protect = inb(pTrident->PIOBase + 0x3C5); 3366 outb(pTrident->PIOBase + 0x3C5, 0x92); 3367 } 3368 outb(pTrident->PIOBase + 0x3C4, NewMode1); 3369 temp = inb(pTrident->PIOBase + 0x3C5); 3370 outb(pTrident->PIOBase + 0x3C5, 0x80); 3371 3372 /* Enable MMIO */ 3373 outb(vgaIOBase + 4, PCIReg); 3374 pTrident->REGPCIReg = inb(vgaIOBase + 5); 3375 outb(vgaIOBase + 5, pTrident->REGPCIReg | 0x01); /* Enable it */ 3376 3377 /* Protect registers */ 3378 if (pTrident->Chipset > PROVIDIA9685) { 3379 OUTB(0x3C4, Protection); 3380 OUTB(0x3C5, protect); 3381 } 3382 OUTB(0x3C4, NewMode1); 3383 OUTB(0x3C5, temp); 3384} 3385 3386static void 3387TRIDENTDisableMMIO(ScrnInfoPtr pScrn) 3388{ 3389 int vgaIOBase = VGAHWPTR(pScrn)->IOBase; 3390 CARD8 temp = 0, protect = 0; 3391 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 3392 3393 /* 3394 * Skip MMIO Disable in PC-9821 PCI Trident Card!! 3395 * Because of lack of non PCI VGA port 3396 */ 3397 if (IsPciCard && xf86IsPc98()) 3398 return; 3399 3400 /* Goto New Mode */ 3401 OUTB(0x3C4, 0x0B); temp = INB(0x3C5); 3402 3403 /* Unprotect registers */ 3404 OUTB(0x3C4, NewMode1); temp = INB(0x3C5); 3405 OUTB(0x3C5, 0x80); 3406 if (pTrident->Chipset > PROVIDIA9685) { 3407 OUTB(0x3C4, Protection); 3408 protect = INB(0x3C5); 3409 OUTB(0x3C5, 0x92); 3410 } 3411 3412 /* Disable MMIO access */ 3413 OUTB(vgaIOBase + 4, PCIReg); 3414 pTrident->REGPCIReg = INB(vgaIOBase + 5); 3415 OUTB(vgaIOBase + 5, pTrident->REGPCIReg & 0xFE); 3416 3417 /* Protect registers */ 3418 if (pTrident->Chipset > PROVIDIA9685) { 3419 outb(pTrident->PIOBase + 0x3C4, Protection); 3420 outb(pTrident->PIOBase + 0x3C5, protect); 3421 } 3422 outb(pTrident->PIOBase + 0x3C4, NewMode1); 3423 outb(pTrident->PIOBase + 0x3C5, temp); 3424} 3425 3426/* Initialize VGA Block for Trident Chip on PC-98x1 */ 3427static void 3428PC98TRIDENTInit(ScrnInfoPtr pScrn) 3429{ 3430 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 3431 switch (pTrident->Chipset) { 3432 case TGUI9660: 3433 case TGUI9680: 3434 case PROVIDIA9682: 3435 PC98TRIDENT96xxInit(pScrn); 3436 break; 3437 case CYBER9320: 3438 case CYBER9385: 3439 PC98TRIDENT9385Init(pScrn); 3440 break; 3441 default: /* Run 96xx code as default */ 3442 PC98TRIDENT96xxInit(pScrn); 3443 break; 3444 } 3445} 3446 3447static void 3448PC98TRIDENTEnable(ScrnInfoPtr pScrn) 3449{ 3450 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 3451 switch (pTrident->Chipset) { 3452 case TGUI9660: 3453 case TGUI9680: 3454 case PROVIDIA9682: 3455 PC98TRIDENT96xxEnable(pScrn); 3456 break; 3457 case CYBER9320: 3458 case CYBER9385: 3459 PC98TRIDENT9385Enable(pScrn); 3460 break; 3461 default: /* Run 96xx code as default */ 3462 PC98TRIDENT96xxEnable(pScrn); 3463 break; 3464 } 3465} 3466 3467static void 3468PC98TRIDENTDisable(ScrnInfoPtr pScrn) 3469{ 3470 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 3471 switch (pTrident->Chipset) { 3472 case TGUI9660: 3473 case TGUI9680: 3474 case PROVIDIA9682: 3475 PC98TRIDENT96xxDisable(pScrn); 3476 break; 3477 case CYBER9320: 3478 case CYBER9385: 3479 PC98TRIDENT9385Disable(pScrn); 3480 break; 3481 default: /* Run 96xx code as default */ 3482 PC98TRIDENT96xxDisable(pScrn); 3483 break; 3484 } 3485} 3486 3487/* Initialize VGA Block for Cyber9385 on PC-98x1 */ 3488static void 3489PC98TRIDENT9385Init(ScrnInfoPtr pScrn) 3490{ 3491/* Nothing to initialize */ 3492} 3493 3494static void 3495PC98TRIDENT9385Enable(ScrnInfoPtr pScrn) 3496{ 3497 outb(0xFAC, 0x02); 3498} 3499 3500static void 3501PC98TRIDENT9385Disable(ScrnInfoPtr pScrn) 3502{ 3503 outb(0xFAC, 0x00); 3504} 3505 3506/* Initialize VGA Block for Trident96xx on PC-98x1 */ 3507static void 3508PC98TRIDENT96xxInit(ScrnInfoPtr pScrn) 3509{ 3510 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 3511 vgaHWPtr hwp = VGAHWPTR(pScrn); 3512 CARD8 temp = 0; 3513 3514 vgaHWProtect(pScrn, TRUE); 3515 3516 /* Video SusSystem Enable */ 3517 temp = INB(0x3CC); 3518 OUTB(0x3C2, temp | 0xC3); 3519 /* Switch Old */ 3520 OUTB(0x3C4, 0x0B); temp = INB(0x3C5); 3521 OUTW(0x3C4, 0x0B | (temp << 8)); 3522 /* Select Configuration Port 1 */ 3523 OUTB(0x3C4, 0x0E); temp = INB(0x3C5); 3524 OUTW(0x3C4, 0x0E | ((temp | 0x20) << 8)); 3525 3526 OUTB(0x3C4, 0x0c); 3527 if((INB(0x3C5) & 0x10) == 0x10) 3528 { 3529 OUTB(0x3C4, 0x0E | (temp << 8)); 3530 OUTB(0x94, 0x00); 3531 OUTB(0x102, 0x01); 3532 OUTB(0x94, 0x20); 3533 temp = INB(0x3C3); 3534 OUTB(0x3C3, temp | 0x01); 3535 } else { 3536 OUTB(0x3C4, 0x0E | (temp << 8)); 3537 OUTB(0x46E8, 0x10); 3538 OUTB(0x102, 0x01); 3539 OUTB(0x46E8, 0x08); 3540 } 3541 3542 INB(0x3DA); 3543 OUTB(0x3C0,0x10); 3544 OUTB(0x3C0,0x41); 3545 3546 /* Register Unlock */ 3547 vgaHWUnlock(hwp); 3548 OUTB(0x3C4, 0x0B); temp = INB(0x3C5); /* Switch New */ 3549 OUTB(0x3C4, 0x0E); temp = INB(0x3C5); 3550 OUTW(0x3C4, 0x0E | ((temp | 0x80) << 8)); 3551 3552 /* For Speed Up [Facoor 2 at Xengine] */ 3553 OUTW(0x3D4, 0x3820); /* Command FIFO Register */ 3554 OUTW(0x3D4, 0x2020); /* Command FIFO Register */ 3555 /* Latency Control Registers 0x30 - 0x32 */ 3556 /* Parameter Range 0x00 - 0x0F */ 3557 /* Tune these parameter to avoid GE Timeout */ 3558 OUTW(0x3D4, 0x0E30); /* Display Queue Latency Control */ 3559 /* 8bpp GE No Timeout Parameter 0x0D - 0x0F for PC-9821Xa7 TGUi9680 */ 3560 OUTW(0x3D4, 0x0031); /* Frame Buffer Latency Control */ 3561 OUTW(0x3D4, 0x0032); /* Display & Frame Buffer Latency Control */ 3562 OUTW(0x3D4, 0x213B); /* Clock and Tuning */ 3563 3564 /* MCLK Init */ 3565 OUTB(0x43C6, 0xAF); OUTB(0x43C7, 0x00); /* 80.0MHz */ 3566#if 0 3567 /* Sample MCLKs */ 3568 OUTB(0x43C6, 0xAF); OUTB(0x43C7, 0x00); /* 80.0MHz */ 3569 OUTB(0x43C6, 0xA7); OUTB(0x43C7, 0x00); /* 77.0MHz */ 3570 OUTB(0x43C6, 0x8E); OUTB(0x43C7, 0x00); /* 75.0MHz */ 3571 OUTB(0x43C6, 0x86); OUTB(0x43C7, 0x00); /* 72.0MHz */ 3572 OUTB(0x43C6, 0x8F); OUTB(0x43C7, 0x00); /* 67.2MHz */ 3573 OUTB(0x43C6, 0xD5); OUTB(0x43C7, 0x02); /* 61.6MHz */ 3574#endif 3575 3576 /* Register Lock */ 3577 OUTB(0x3C4, 0x0B); temp = INB(0x3C5); /* Switch New */ 3578 OUTB(0x3C4, 0x0E); temp = INB(0x3C5); 3579 OUTW(0x3C4, 0x0E | ((temp & 0x7F) << 8)); 3580 vgaHWLock(hwp); 3581 3582 vgaHWProtect(pScrn, FALSE); 3583} 3584 3585static void 3586PC98TRIDENT96xxEnable(ScrnInfoPtr pScrn) 3587{ 3588 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 3589 CARD8 temp = 0; 3590 3591 outb(0x68, 0x0E); 3592 outb(0x6A, 0x07); 3593 outb(0x6A, 0x8F); 3594 outb(0x6A, 0x06); 3595 3596 vgaHWProtect(pScrn, TRUE); 3597 3598 OUTB(0x3D4, 0x23); temp = INB(0x3D5); 3599 OUTW(0x3D4, 0x23 | ((temp & 0xDF) << 8)); 3600 3601 OUTB(0x3D4, 0x29); temp = INB(0x3D5); 3602 OUTW(0x3D4, 0x29 | ((temp | 0x04) << 8)); 3603 3604 OUTB(0x83C8, 0x04); temp = INB(0x83c6); 3605 OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x06)); 3606 3607 OUTB(0x83C8, 0x04); temp = INB(0x83c6); 3608 OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x08)); 3609 3610 OUTB(0x3CE, 0x23); temp = INB(0x3CF); 3611 OUTW(0x3CE, 0x23 | ((temp & 0xFC) << 8)); 3612 3613 OUTB(0x83C8, 0x04); temp = INB(0x83c6); 3614 OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp | 0x01)); 3615 3616 OUTB(0x3C4, 0x01); temp = INB(0x3C5); 3617 OUTW(0x3C4, 0x01 | ((temp & 0xEF) << 8)); 3618 3619 vgaHWProtect(pScrn, FALSE); 3620 3621 outb(0xFAC, 0x02); 3622} 3623 3624static void 3625PC98TRIDENT96xxDisable(ScrnInfoPtr pScrn) 3626{ 3627 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 3628 CARD8 temp = 0; 3629 3630 outb(0xFAC, 0x00); 3631 3632 vgaHWProtect(pScrn, TRUE); 3633 3634 OUTB(0x3C4, 0x01); temp = INB(0x3C5); 3635 OUTW(0x3C4, 0x01 | ((temp | 0x10) << 8)); 3636 3637 OUTB(0x83C8, 0x04); temp = INB(0x83c6); 3638 OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFE)); 3639 3640 OUTB(0x3CE, 0x23); temp = INB(0x3CF); 3641 OUTW(0x3CE, 0x23 | (((temp & 0xFC) | 0x01) << 8)); 3642 3643 OUTB(0x83C8, 0x04); temp = INB(0x83c6); 3644 OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFD)); 3645 3646 OUTB(0x83C8, 0x04); temp = INB(0x83c6); 3647 OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xCF)); 3648 3649 OUTB(0x83C8, 0x04); temp = INB(0x83c6); 3650 OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xF7)); 3651 3652 OUTB(0x83C8, 0x04); temp = INB(0x83c6); 3653 OUTB(0x83C8, 0x04); OUTB(0x83c6, (temp & 0xFB)); 3654 3655 OUTB(0x3D4, 0x29); temp = INB(0x3D5); 3656 OUTW(0x3D4, 0x29 | ((temp & 0xFB) << 8)); 3657 3658 OUTB(0x3D4, 0x23); temp = INB(0x3D5); 3659 OUTW(0x3D4, 0x23 | ((temp | 0x20) << 8)); 3660 3661 vgaHWProtect(pScrn, FALSE); 3662 3663 outb(0x6A, 0x07); 3664 outb(0x6A, 0x8E); 3665 outb(0x6A, 0x06); 3666 outb(0x68, 0x0F); 3667} 3668 3669 3670/* 3671 * This is a terrible hack! If we are on a notebook in a stretched 3672 * mode and don't want full screen we use the BIOS to set an unstreched 3673 * mode. 3674 */ 3675void 3676tridentSetModeBIOS(ScrnInfoPtr pScrn, DisplayModePtr mode) 3677{ 3678 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); 3679 3680 3681#ifdef VBE_INFO 3682 if (pTrident->vbeModes) { 3683 vbeSaveRestoreRec vbesr; 3684 vbesr.stateMode = VBECalcVbeModeIndex(pTrident->vbeModes, 3685 mode, pScrn->bitsPerPixel); 3686 vbesr.pstate = NULL; 3687 if (vbesr.stateMode) { 3688 if (IsPciCard && UseMMIO) 3689 TRIDENTDisableMMIO(pScrn); 3690 VBEVesaSaveRestore(pTrident->pVbe,&vbesr,MODE_RESTORE); 3691 if (IsPciCard && UseMMIO) 3692 TRIDENTEnableMMIO(pScrn); 3693 return; 3694 } else 3695 xf86DrvMsg(pScrn->scrnIndex,X_WARNING,"No BIOS Mode matches " 3696 "%ix%I@%ibpp\n",mode->HDisplay,mode->VDisplay, 3697 pScrn->bitsPerPixel); 3698 } 3699#endif 3700 /* This function is only for LCD screens, and also when we have 3701 * int10 available */ 3702 3703 if (pTrident->IsCyber && pTrident->lcdMode && pTrident->Int10) { 3704 int i = pTrident->lcdMode; 3705 if ((pScrn->currentMode->HDisplay != LCD[i].display_x) /* !fullsize? */ 3706 || (pScrn->currentMode->VDisplay != LCD[i].display_y)) { 3707 if (pTrident->lcdActive) { /* LCD Active ?*/ 3708 int h_str, v_str; 3709 3710 OUTB(0x3CE,HorStretch); h_str = INB(0x3CF) & 0x01; 3711 OUTB(0x3CE,VertStretch); v_str = INB(0x3CF) & 0x01; 3712 if (h_str || v_str) { 3713 OUTB(0x3C4, 0x11); OUTB(0x3C5, 0x92); 3714 OUTW(0x3CE, BiosReg ); 3715 pTrident->Int10->ax = 0x3; 3716 pTrident->Int10->num = 0x10; 3717 if (IsPciCard && UseMMIO) 3718 TRIDENTDisableMMIO(pScrn); 3719 xf86ExecX86int10(pTrident->Int10); 3720 if (IsPciCard && UseMMIO) 3721 TRIDENTEnableMMIO(pScrn); 3722 } 3723 } 3724 } 3725 } 3726} 3727 3728/* Currently we only test for 1400 */ 3729static int 3730TRIDENTLcdDisplaySize (xf86MonPtr pMon) 3731{ 3732 if (pMon) { 3733 int i,j; 3734 3735 for (i = 0; i < STD_TIMINGS; i++) { 3736 if (pMon->timings2[i].hsize == 1400) { 3737 return 1400; 3738 } 3739 } 3740 /* 3741 * If not explicitely set try to find out if the display supports 3742 * the 1400 mode. For sanity check if DDC comes from a digital 3743 * display. 3744 */ 3745 if (DIGITAL(pMon->features.input_type)) { 3746 for (i = 0; i < DET_TIMINGS; i++) { 3747 if (pMon->det_mon[i].type == DS_STD_TIMINGS) { 3748 for (j = 0; j < 5; j++) { 3749 if (pMon->det_mon[i].section.std_t[j].hsize == 1400) { 3750 return 1400; 3751 } 3752 } 3753 } else if (pMon->det_mon[i].type == DT) { 3754 if (pMon->det_mon[i].section.d_timings.h_active == 1400) { 3755 return 1400; 3756 } 3757 } 3758 } 3759 } 3760 } 3761 return 0; 3762} 3763 3764