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