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