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