mga_driver.c revision fe5e51b7
1/* $XConsortium: mga_driver.c /main/12 1996/10/28 05:13:26 kaleb $ */ 2/* 3 * MGA Millennium (MGA2064W) with Ti3026 RAMDAC driver v.1.1 4 * 5 * The driver is written without any chip documentation. All extended ports 6 * and registers come from tracing the VESA-ROM functions. 7 * The BitBlt Engine comes from tracing the windows BitBlt function. 8 * 9 * Author: Radoslaw Kapitan, Tarnow, Poland 10 * kapitan@student.uci.agh.edu.pl 11 * original source 12 * 13 * Now that MATROX has released documentation to the public, enhancing 14 * this driver has become much easier. Nevertheless, this work continues 15 * to be based on Radoslaw's original source 16 * 17 * Contributors: 18 * Andrew van der Stock 19 * ajv@greebo.net 20 * additions, corrections, cleanups 21 * 22 * Dirk Hohndel 23 * hohndel@XFree86.Org 24 * integrated into XFree86-3.1.2Gg 25 * fixed some problems with PCI probing and mapping 26 * 27 * David Dawes 28 * dawes@XFree86.Org 29 * some cleanups, and fixed some problems 30 * 31 * Andrew E. Mileski 32 * aem@ott.hookup.net 33 * RAMDAC timing, and BIOS stuff 34 * 35 * Leonard N. Zubkoff 36 * lnz@dandelion.com 37 * Support for 8MB boards, RGB Sync-on-Green, and DPMS. 38 * Guy DESBIEF 39 * g.desbief@aix.pacwan.net 40 * RAMDAC MGA1064 timing, 41 * Doug Merritt 42 * doug@netcom.com 43 * Fixed 32bpp hires 8MB horizontal line glitch at middle right 44 * Niels Gram Jeppesen 45 * Added digital screen option for first head 46 */ 47 48/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c,v 1.244tsi Exp $ */ 49 50#ifdef HAVE_CONFIG_H 51#include "config.h" 52#endif 53 54/* All drivers should typically include these */ 55#include "xf86.h" 56#include "xf86_OSproc.h" 57#include "xf86Resources.h" 58 59/* All drivers need this */ 60 61#include "compiler.h" 62 63/* Drivers for PCI hardware need this */ 64#include "xf86PciInfo.h" 65 66/* Drivers that need to access the PCI config space directly need this */ 67#ifndef XSERVER_LIBPCIACCESS 68#include "xf86Pci.h" 69#endif 70 71/* All drivers initialising the SW cursor need this */ 72#include "mipointer.h" 73 74/* All drivers implementing backing store need this */ 75#include "mibstore.h" 76 77#include "micmap.h" 78 79#include "xf86DDC.h" 80#include "xf86RAC.h" 81#include "vbe.h" 82 83#include "fb.h" 84#include "dixstruct.h" 85 86#include "mga_reg.h" 87#include "mga.h" 88#include "mga_macros.h" 89#include "mga_maven.h" 90 91#ifdef USE_XAA 92#include "xaa.h" 93#endif 94 95#include "xf86cmap.h" 96#include "shadowfb.h" 97#include "fbdevhw.h" 98 99#include "cfb8_32.h" 100 101#ifdef XF86DRI 102#include "dri.h" 103#endif 104 105#include <unistd.h> 106 107/* 108 * Forward definitions for the functions that make up the driver. 109 */ 110 111/* Mandatory functions */ 112static const OptionInfoRec * MGAAvailableOptions(int chipid, int busid); 113static void MGAIdentify(int flags); 114#ifdef XSERVER_LIBPCIACCESS 115static Bool MGAPciProbe(DriverPtr drv, int entity_num, 116 struct pci_device * dev, intptr_t match_data); 117#else 118static Bool MGAProbe(DriverPtr drv, int flags); 119#endif 120static Bool MGAPreInit(ScrnInfoPtr pScrn, int flags); 121static Bool MGAScreenInit(int Index, ScreenPtr pScreen, int argc, 122 char **argv); 123static Bool MGAEnterVT(int scrnIndex, int flags); 124static Bool MGAEnterVTFBDev(int scrnIndex, int flags); 125static void MGALeaveVT(int scrnIndex, int flags); 126static Bool MGACloseScreen(int scrnIndex, ScreenPtr pScreen); 127static Bool MGASaveScreen(ScreenPtr pScreen, int mode); 128static Bool MGASaveScreenCrtc2(ScreenPtr pScreen, int mode); 129 130/* This shouldn't be needed since RAC will disable all I/O for MGA cards. */ 131#ifdef DISABLE_VGA_IO 132static void VgaIOSave(int i, void *arg); 133static void VgaIORestore(int i, void *arg); 134#endif 135 136/* Optional functions */ 137static void MGAFreeScreen(int scrnIndex, int flags); 138static ModeStatus MGAValidMode(int scrnIndex, DisplayModePtr mode, 139 Bool verbose, int flags); 140 141#if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ >= 4) 142#define __must_check __attribute__((warn_unused_result)) 143#else 144#define __must_check /* */ 145#endif 146 147/* Internally used functions */ 148static Bool __must_check MGAMapMem(ScrnInfoPtr pScrn); 149static Bool MGAUnmapMem(ScrnInfoPtr pScrn); 150static void MGASave(ScrnInfoPtr pScrn); 151static void MGARestore(ScrnInfoPtr pScrn); 152static Bool MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); 153static void MGABlockHandler(int, pointer, pointer, pointer); 154static void MGAG100BlackMagic(ScrnInfoPtr pScrn); 155 156static int MGAEntityIndex = -1; 157 158#include "mga_merge.h" 159 160static const struct mga_device_attributes attribs[8] = { 161 /* 2064 */ 162 [0] = { 1, 0, 0, 1, 0, 0, 0, 0, old_BARs, 163 (BLK_OPAQUE_EXPANSION | FASTBLT_BUG | USE_LINEAR_EXPANSION) }, 164 165 /* 1064 */ 166 [1] = { 0, 1, 0, 0, 1, 0, 0, 0, probe_BARs, 167 (USE_LINEAR_EXPANSION) }, 168 169 /* 2164, 2164 AGP */ 170 [2] = { 1, 0, 0, 1, 0, 0, 0, 0, new_BARs, 171 (BLK_OPAQUE_EXPANSION | TRANSC_SOLID_FILL | USE_RECTS_FOR_LINES 172 | USE_LINEAR_EXPANSION) }, 173 174 /* G100 */ 175 [3] = { 0, 1, 0, 0, 1, 0, 0, 0, new_BARs, 176 (MGA_NO_PLANEMASK | USE_LINEAR_EXPANSION) }, 177 178 /* G200 */ 179 [4] = { 0, 1, 0, 0, 1, 1, 1, 1, new_BARs, 180 (TRANSC_SOLID_FILL | TWO_PASS_COLOR_EXPAND | USE_LINEAR_EXPANSION) }, 181 182 /* G400 / G450 */ 183 [5] = { 0, 1, 1, 0, 1, 1, 2, 1, new_BARs, 184 (TRANSC_SOLID_FILL | TWO_PASS_COLOR_EXPAND | USE_LINEAR_EXPANSION) }, 185 186 /* G550 */ 187 [6] = { 0, 1, 1, 0, 1, 1, 2, 1, new_BARs, 188 (TRANSC_SOLID_FILL | TWO_PASS_COLOR_EXPAND | USE_LINEAR_EXPANSION) }, 189 190 /* G200SE */ 191 [7] = { 0, 1, 0, 0, 1, 0, 0, 1, new_BARs, 192 (TRANSC_SOLID_FILL | TWO_PASS_COLOR_EXPAND | USE_LINEAR_EXPANSION) }, 193}; 194 195#ifdef XSERVER_LIBPCIACCESS 196#define MGA_DEVICE_MATCH(d, i) \ 197 { 0x102B, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) } 198#define MGA_SUBDEVICE_MATCH(d, s, i) \ 199 { 0x102B, (d), 0x102B, (s), 0, 0, (i) } 200 201static const struct pci_id_match mga_device_match[] = { 202 MGA_DEVICE_MATCH( PCI_CHIP_MGA2064, 0 ), 203 MGA_DEVICE_MATCH( PCI_CHIP_MGA1064, 1 ), 204 MGA_DEVICE_MATCH( PCI_CHIP_MGA2164, 2 ), 205 MGA_DEVICE_MATCH( PCI_CHIP_MGA2164_AGP, 2 ), 206 MGA_DEVICE_MATCH( PCI_CHIP_MGAG100, 3 ), 207 MGA_DEVICE_MATCH( PCI_CHIP_MGAG100_PCI, 3 ), 208 MGA_DEVICE_MATCH( PCI_CHIP_MGAG200, 4 ), 209 MGA_DEVICE_MATCH( PCI_CHIP_MGAG200_PCI, 4 ), 210 MGA_DEVICE_MATCH( PCI_CHIP_MGAG400, 5 ), 211 MGA_DEVICE_MATCH( PCI_CHIP_MGAG550, 6 ), 212 213 MGA_DEVICE_MATCH( PCI_CHIP_MGAG200_SE_A_PCI, 7 ), 214 MGA_DEVICE_MATCH( PCI_CHIP_MGAG200_SE_B_PCI, 7 ), 215 216 { 0, 0, 0 }, 217}; 218#endif 219 220/* Supported chipsets */ 221static SymTabRec MGAChipsets[] = { 222 { PCI_CHIP_MGA2064, "mga2064w" }, 223 { PCI_CHIP_MGA1064, "mga1064sg" }, 224 { PCI_CHIP_MGA2164, "mga2164w" }, 225 { PCI_CHIP_MGA2164_AGP, "mga2164w AGP" }, 226 { PCI_CHIP_MGAG100, "mgag100" }, 227 { PCI_CHIP_MGAG100_PCI, "mgag100 PCI" }, 228 { PCI_CHIP_MGAG200, "mgag200" }, 229 { PCI_CHIP_MGAG200_PCI, "mgag200 PCI" }, 230 { PCI_CHIP_MGAG200_SE_A_PCI, "mgag200 SE A PCI" }, 231 { PCI_CHIP_MGAG200_SE_B_PCI, "mgag200 SE B PCI" }, 232 { PCI_CHIP_MGAG400, "mgag400" }, 233 { PCI_CHIP_MGAG550, "mgag550" }, 234 {-1, NULL } 235}; 236 237static PciChipsets MGAPciChipsets[] = { 238 { PCI_CHIP_MGA2064, PCI_CHIP_MGA2064, (resRange*)RES_SHARED_VGA }, 239 { PCI_CHIP_MGA1064, PCI_CHIP_MGA1064, (resRange*)RES_SHARED_VGA }, 240 { PCI_CHIP_MGA2164, PCI_CHIP_MGA2164, (resRange*)RES_SHARED_VGA }, 241 { PCI_CHIP_MGA2164_AGP, PCI_CHIP_MGA2164_AGP,(resRange*)RES_SHARED_VGA }, 242 { PCI_CHIP_MGAG100, PCI_CHIP_MGAG100, (resRange*)RES_SHARED_VGA }, 243 { PCI_CHIP_MGAG100_PCI, PCI_CHIP_MGAG100_PCI,(resRange*)RES_SHARED_VGA }, 244 { PCI_CHIP_MGAG200, PCI_CHIP_MGAG200, (resRange*)RES_SHARED_VGA }, 245 { PCI_CHIP_MGAG200_PCI, PCI_CHIP_MGAG200_PCI,(resRange*)RES_SHARED_VGA }, 246 { PCI_CHIP_MGAG200_SE_B_PCI, PCI_CHIP_MGAG200_SE_B_PCI, 247 (resRange*)RES_SHARED_VGA }, 248 { PCI_CHIP_MGAG200_SE_A_PCI, PCI_CHIP_MGAG200_SE_A_PCI, 249 (resRange*)RES_SHARED_VGA }, 250 { PCI_CHIP_MGAG400, PCI_CHIP_MGAG400, (resRange*)RES_SHARED_VGA }, 251 { PCI_CHIP_MGAG550, PCI_CHIP_MGAG550, (resRange*)RES_SHARED_VGA }, 252 { -1, -1, (resRange*)RES_UNDEFINED } 253}; 254 255/* 256 * This contains the functions needed by the server after loading the 257 * driver module. It must be supplied, and gets added the driver list by 258 * the Module Setup funtion in the dynamic case. In the static case a 259 * reference to this is compiled in, and this requires that the name of 260 * this DriverRec be an upper-case version of the driver name. 261 */ 262 263_X_EXPORT DriverRec MGA_C_NAME = { 264 MGA_VERSION, 265 MGA_DRIVER_NAME, 266 MGAIdentify, 267#ifdef XSERVER_LIBPCIACCESS 268 NULL, 269#else 270 MGAProbe, 271#endif 272 MGAAvailableOptions, 273 NULL, 274 0, 275 NULL, 276 277#ifdef XSERVER_LIBPCIACCESS 278 mga_device_match, 279 MGAPciProbe 280#endif 281}; 282 283 284static const OptionInfoRec MGAOptions[] = { 285 { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, 286 { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, 287 { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE }, 288 { OPTION_SYNC_ON_GREEN, "SyncOnGreen", OPTV_BOOLEAN, {0}, FALSE }, 289 { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 290 { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE }, 291 { OPTION_OVERLAY, "Overlay", OPTV_ANYSTR, {0}, FALSE }, 292 { OPTION_MGA_SDRAM, "MGASDRAM", OPTV_BOOLEAN, {0}, FALSE }, 293 { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, 294 { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE }, 295 { OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE }, 296 { OPTION_SET_MCLK, "SetMclk", OPTV_FREQ, {0}, FALSE }, 297 { OPTION_OVERCLOCK_MEM, "OverclockMem", OPTV_BOOLEAN, {0}, FALSE }, 298 { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE }, 299 { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, 300 { OPTION_TEXTURED_VIDEO, "TexturedVideo",OPTV_BOOLEAN, {0}, FALSE }, 301 { OPTION_CRTC2HALF, "Crtc2Half", OPTV_BOOLEAN, {0}, FALSE }, 302 { OPTION_CRTC2RAM, "Crtc2Ram", OPTV_INTEGER, {0}, FALSE }, 303 { OPTION_INT10, "Int10", OPTV_BOOLEAN, {0}, FALSE }, 304 { OPTION_AGP_MODE, "AGPMode", OPTV_INTEGER, {0}, FALSE }, 305 { OPTION_AGP_SIZE, "AGPSize", OPTV_INTEGER, {0}, FALSE }, 306 { OPTION_DIGITAL1, "DigitalScreen1",OPTV_BOOLEAN, {0}, FALSE }, 307 { OPTION_DIGITAL2, "DigitalScreen2",OPTV_BOOLEAN, {0}, FALSE }, 308 { OPTION_TV, "TV", OPTV_BOOLEAN, {0}, FALSE }, 309 { OPTION_TVSTANDARD, "TVStandard", OPTV_ANYSTR, {0}, FALSE }, 310 { OPTION_CABLETYPE, "CableType", OPTV_ANYSTR, {0}, FALSE }, 311 { OPTION_NOHAL, "NoHal", OPTV_BOOLEAN, {0}, FALSE }, 312 { OPTION_SWAPPED_HEAD, "SwappedHead", OPTV_BOOLEAN, {0}, FALSE }, 313 { OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE }, 314 { OPTION_MERGEDFB, "MergedFB", OPTV_BOOLEAN, {0}, FALSE }, 315 { OPTION_HSYNC2, "Monitor2HSync", OPTV_ANYSTR, {0}, FALSE }, 316 { OPTION_VREFRESH2, "Monitor2VRefresh", OPTV_ANYSTR, {0}, FALSE }, 317 { OPTION_MONITOR2POS, "Monitor2Position", OPTV_ANYSTR, {0}, FALSE }, 318 { OPTION_METAMODES, "MetaModes", OPTV_ANYSTR, {0}, FALSE }, 319 { OPTION_OLDDMA, "OldDmaInit", OPTV_BOOLEAN, {0}, FALSE }, 320 { OPTION_PCIDMA, "ForcePciDma", OPTV_BOOLEAN, {0}, FALSE }, 321 { OPTION_ACCELMETHOD, "AccelMethod", OPTV_ANYSTR, {0}, FALSE }, 322 { -1, NULL, OPTV_NONE, {0}, FALSE } 323}; 324 325 326/* 327 * List of symbols from other modules that this module references. This 328 * list is used to tell the loader that it is OK for symbols here to be 329 * unresolved providing that it hasn't been told that they haven't been 330 * told that they are essential via a call to xf86LoaderReqSymbols() or 331 * xf86LoaderReqSymLists(). The purpose is this is to avoid warnings about 332 * unresolved symbols that are not required. 333 */ 334 335static const char *vgahwSymbols[] = { 336 "vgaHWFreeHWRec", 337 "vgaHWGetHWRec", 338 "vgaHWGetIOBase", 339 "vgaHWGetIndex", 340 "vgaHWInit", 341 "vgaHWLock", 342 "vgaHWMapMem", 343 "vgaHWProtect", 344 "vgaHWRestore", 345 "vgaHWSave", 346 "vgaHWSaveScreen", 347 "vgaHWSetMmioFuncs", 348 "vgaHWUnlock", 349 "vgaHWUnmapMem", 350 "vgaHWddc1SetSpeedWeak", 351 NULL 352}; 353 354static const char *fbSymbols[] = { 355 "fbPictureInit", 356 "fbScreenInit", 357 NULL 358}; 359 360static const char *xf8_32bppSymbols[] = { 361 "cfb8_32ScreenInit", 362 "xf86Overlay8Plus32Init", 363 NULL 364}; 365 366#ifdef USE_EXA 367static const char *exaSymbols[] = { 368 "exaDriverInit", 369 "exaDriverFini", 370 "exaGetPixmapOffset", 371 "exaGetVersion", 372 NULL 373}; 374#endif 375 376#ifdef USE_XAA 377static const char *xaaSymbols[] = { 378 "XAACachePlanarMonoStipple", 379 "XAACreateInfoRec", 380 "XAADestroyInfoRec", 381 "XAAGetFallbackOps", 382 "XAAInit", 383 "XAAMoveDWORDS", 384 "XAA_888_plus_PICT_a8_to_8888", 385 NULL 386}; 387#endif 388 389static const char *ramdacSymbols[] = { 390 "xf86CreateCursorInfoRec", 391 "xf86DestroyCursorInfoRec", 392 "xf86InitCursor", 393 NULL 394}; 395 396#ifdef XF86DRI 397static const char *drmSymbols[] = { 398 "drmAddBufs", 399 "drmAddMap", 400 "drmAgpAcquire", 401 "drmAgpAlloc", 402 "drmAgpBind", 403 "drmAgpDeviceId", 404 "drmAgpEnable", 405 "drmAgpFree", 406 "drmAgpGetMode", 407 "drmAgpRelease", 408 "drmAgpUnbind", 409 "drmAgpVendorId", 410 "drmCommandNone", 411 "drmCommandWrite", 412 "drmCtlInstHandler", 413 "drmCtlUninstHandler", 414 "drmFreeVersion", 415 "drmGetInterruptFromBusID", 416 "drmGetLibVersion", 417 "drmGetVersion", 418 "drmMap", 419 "drmMapBufs", 420 "drmUnmap", 421 "drmUnmapBufs", 422 NULL 423}; 424 425static const char *driSymbols[] = { 426 "DRICloseScreen", 427 "DRICreateInfoRec", 428 "DRIDestroyInfoRec", 429 "DRIFinishScreenInit", 430 "DRIGetDeviceInfo", 431 "DRILock", 432 "DRIQueryVersion", 433 "DRIScreenInit", 434 "DRIUnlock", 435 "GlxSetVisualConfigs", 436 "DRICreatePCIBusID", 437 NULL 438}; 439#endif 440 441#define MGAuseI2C 1 442 443static const char *ddcSymbols[] = { 444 "xf86DoEDID_DDC1", 445#if MGAuseI2C 446 "xf86DoEDID_DDC2", 447#endif 448 "xf86PrintEDID", 449 "xf86SetDDCproperties", 450 NULL 451}; 452 453static const char *i2cSymbols[] = { 454 "xf86CreateI2CBusRec", 455 "xf86I2CBusInit", 456 NULL 457}; 458 459static const char *shadowSymbols[] = { 460 "ShadowFBInit", 461 NULL 462}; 463 464#ifdef XFree86LOADER 465static const char *vbeSymbols[] = { 466 "VBEInit", 467 "vbeDoEDID", 468 "vbeFree", 469 NULL 470}; 471#endif 472 473static const char *int10Symbols[] = { 474 "xf86FreeInt10", 475 "xf86InitInt10", 476 NULL 477}; 478 479static const char *fbdevHWSymbols[] = { 480 "fbdevHWAdjustFrameWeak", 481 "fbdevHWEnterVT", 482 "fbdevHWGetVidmem", 483 "fbdevHWInit", 484 "fbdevHWLeaveVTWeak", 485 "fbdevHWLoadPaletteWeak", 486 "fbdevHWMapMMIO", 487 "fbdevHWMapVidmem", 488 "fbdevHWModeInit", 489 "fbdevHWRestore", 490 "fbdevHWSave", 491 "fbdevHWSwitchModeWeak", 492 "fbdevHWUnmapMMIO", 493 "fbdevHWUnmapVidmem", 494 "fbdevHWUseBuildinMode", 495 "fbdevHWValidModeWeak", 496 NULL 497}; 498 499#ifdef USEMGAHAL 500static const char *halSymbols[] = { 501 "MGACloseLibrary", 502 "MGAGetBOARDHANDLESize", 503 "MGAGetHardwareInfo", 504 "MGAOpenLibrary", 505 "MGARestoreVgaState", 506 "MGASaveVgaState", 507 "MGASetMode", 508 "MGASetVgaMode", 509 "MGAValidateMode", 510 "MGAValidateVideoParameters", 511 "HALSetDisplayStart", 512 NULL 513}; 514#endif 515#ifdef XFree86LOADER 516 517static MODULESETUPPROTO(mgaSetup); 518 519static XF86ModuleVersionInfo mgaVersRec = 520{ 521 MGA_DRIVER_NAME, 522 MODULEVENDORSTRING, 523 MODINFOSTRING1, 524 MODINFOSTRING2, 525 XORG_VERSION_CURRENT, 526 PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL, 527 ABI_CLASS_VIDEODRV, /* This is a video driver */ 528 ABI_VIDEODRV_VERSION, 529 MOD_CLASS_VIDEODRV, 530 {0,0,0,0} 531}; 532 533_X_EXPORT XF86ModuleData MGA_MODULE_DATA = { &mgaVersRec, mgaSetup, NULL }; 534 535static pointer 536mgaSetup(pointer module, pointer opts, int *errmaj, int *errmin) 537{ 538 static Bool setupDone = FALSE; 539 540 /* This module should be loaded only once, but check to be sure. */ 541 542 if (!setupDone) { 543 setupDone = TRUE; 544 xf86AddDriver(&MGA_C_NAME, module, 1); 545 546 /* 547 * Modules that this driver always requires may be loaded here 548 * by calling LoadSubModule(). 549 */ 550 551 /* 552 * Tell the loader about symbols from other modules that this module 553 * might refer to. 554 */ 555 LoaderRefSymLists(vgahwSymbols, 556#ifdef USE_XAA 557 xaaSymbols, 558#endif 559#ifdef USE_EXA 560 exaSymbols, 561#endif 562 xf8_32bppSymbols, ramdacSymbols, 563 ddcSymbols, i2cSymbols, shadowSymbols, 564 fbdevHWSymbols, vbeSymbols, 565 fbSymbols, int10Symbols, 566#ifdef XF86DRI 567 drmSymbols, driSymbols, 568#endif 569#ifdef USEMGAHAL 570 halSymbols, 571#endif 572 NULL); 573 574 /* 575 * The return value must be non-NULL on success even though there 576 * is no TearDownProc. 577 */ 578 return (pointer)1; 579 } else { 580 if (errmaj) *errmaj = LDR_ONCEONLY; 581 return NULL; 582 } 583} 584 585 586#endif /* XFree86LOADER */ 587 588/* 589 * ramdac info structure initialization 590 */ 591static MGARamdacRec DacInit = { 592 FALSE, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, 593 90000, /* maxPixelClock */ 594 0, X_DEFAULT, X_DEFAULT, FALSE 595}; 596 597Bool 598MGAGetRec(ScrnInfoPtr pScrn) 599{ 600 /* 601 * Allocate an MGARec, and hook it into pScrn->driverPrivate. 602 * pScrn->driverPrivate is initialised to NULL, so we can check if 603 * the allocation has already been done. 604 */ 605 if (pScrn->driverPrivate != NULL) 606 return TRUE; 607 608 pScrn->driverPrivate = xnfcalloc(sizeof(MGARec), 1); 609 /* Initialise it */ 610 611 MGAPTR(pScrn)->Dac = DacInit; 612 return TRUE; 613} 614 615void 616MGAFreeRec(ScrnInfoPtr pScrn) 617{ 618 if (pScrn->driverPrivate == NULL) 619 return; 620 xfree(pScrn->driverPrivate); 621 pScrn->driverPrivate = NULL; 622} 623 624static const OptionInfoRec * 625MGAAvailableOptions(int chipid, int busid) 626{ 627 return MGAOptions; 628} 629 630/* Mandatory */ 631static void 632MGAIdentify(int flags) 633{ 634 xf86PrintChipsets(MGA_NAME, "driver for Matrox chipsets", MGAChipsets); 635} 636 637 638#ifdef XSERVER_LIBPCIACCESS 639Bool 640MGAPciProbe(DriverPtr drv, int entity_num, struct pci_device * dev, 641 intptr_t match_data) 642{ 643 ScrnInfoPtr pScrn = NULL; 644 EntityInfoPtr pEnt; 645 MGAPtr pMga; 646#ifdef DISABLE_VGA_IO 647 MgaSavePtr smga; 648 649 650 smga = xnfalloc(sizeof(MgaSave)); 651 smga->pvp = dev; 652#endif 653 654 /* Allocate a ScrnInfoRec and claim the slot */ 655 pScrn = xf86ConfigPciEntity(pScrn, 0, entity_num, MGAPciChipsets, 656 NULL, 657#ifndef DISABLE_VGA_IO 658 NULL, NULL, NULL, NULL 659#else 660 VgaIOSave, VgaIOSave, VgaIORestore, smga 661#endif 662 ); 663 if (pScrn != NULL) { 664 /* Fill in what we can of the ScrnInfoRec */ 665 pScrn->driverVersion = MGA_VERSION; 666 pScrn->driverName = MGA_DRIVER_NAME; 667 pScrn->name = MGA_NAME; 668 pScrn->Probe = NULL; 669 pScrn->PreInit = MGAPreInit; 670 pScrn->ScreenInit = MGAScreenInit; 671 pScrn->SwitchMode = MGASwitchMode; 672 pScrn->AdjustFrame = MGAAdjustFrame; 673 pScrn->EnterVT = MGAEnterVT; 674 pScrn->LeaveVT = MGALeaveVT; 675 pScrn->FreeScreen = MGAFreeScreen; 676 pScrn->ValidMode = MGAValidMode; 677 678 679 /* Allocate the MGARec driverPrivate */ 680 if (!MGAGetRec(pScrn)) { 681 return FALSE; 682 } 683 684 pMga = MGAPTR(pScrn); 685 pMga->chip_attribs = & attribs[ match_data ]; 686 pMga->PciInfo = dev; 687 688 689 /* 690 * For cards that can do dual head per entity, mark the entity 691 * as sharable. 692 */ 693 pEnt = xf86GetEntityInfo(entity_num); 694 if (pMga->chip_attribs->dual_head_possible) { 695 MGAEntPtr pMgaEnt = NULL; 696 DevUnion *pPriv; 697 698 xf86SetEntitySharable(entity_num); 699 /* Allocate an entity private if necessary */ 700 if (MGAEntityIndex < 0) 701 MGAEntityIndex = xf86AllocateEntityPrivateIndex(); 702 pPriv = xf86GetEntityPrivate(pScrn->entityList[0], MGAEntityIndex); 703 if (!pPriv->ptr) { 704 pPriv->ptr = xnfcalloc(sizeof(MGAEntRec), 1); 705 pMgaEnt = pPriv->ptr; 706 pMgaEnt->lastInstance = -1; 707 } else { 708 pMgaEnt = pPriv->ptr; 709 } 710 /* 711 * Set the entity instance for this instance of the driver. For 712 * dual head per card, instance 0 is the "master" instance, driving 713 * the primary head, and instance 1 is the "slave". 714 */ 715 pMgaEnt->lastInstance++; 716 xf86SetEntityInstanceForScreen(pScrn, pScrn->entityList[0], 717 pMgaEnt->lastInstance); 718 } 719 } 720 721 return (pScrn != NULL); 722} 723 724#else 725 726/* Mandatory */ 727static Bool 728MGAProbe(DriverPtr drv, int flags) 729{ 730 int i; 731 GDevPtr *devSections; 732 int *usedChips = NULL; 733 int numDevSections; 734 int numUsed; 735 Bool foundScreen = FALSE; 736 737 /* 738 * The aim here is to find all cards that this driver can handle, 739 * and for the ones not already claimed by another driver, claim the 740 * slot, and allocate a ScrnInfoRec. 741 * 742 * This should be a minimal probe, and it should under no circumstances 743 * change the state of the hardware. Because a device is found, don't 744 * assume that it will be used. Don't do any initialisations other than 745 * the required ScrnInfoRec initialisations. Don't allocate any new 746 * data structures. 747 */ 748 749 /* 750 * Check if there has been a chipset override in the config file. 751 * For this we must find out if there is an active device section which 752 * is relevant, i.e., which has no driver specified or has THIS driver 753 * specified. 754 */ 755 756 if ((numDevSections = xf86MatchDevice(MGA_DRIVER_NAME, 757 &devSections)) <= 0) { 758 /* 759 * There's no matching device section in the config file, so quit 760 * now. 761 */ 762 return FALSE; 763 } 764 765 /* 766 * We need to probe the hardware first. We then need to see how this 767 * fits in with what is given in the config file, and allow the config 768 * file info to override any contradictions. 769 */ 770 771 /* 772 * All of the cards this driver supports are PCI, so the "probing" just 773 * amounts to checking the PCI data that the server has already collected. 774 */ 775 if (xf86GetPciVideoInfo() == NULL) { 776 /* 777 * We won't let anything in the config file override finding no 778 * PCI video cards at all. This seems reasonable now, but we'll see. 779 */ 780 return FALSE; 781 } 782 783 numUsed = xf86MatchPciInstances(MGA_NAME, PCI_VENDOR_MATROX, 784 MGAChipsets, MGAPciChipsets, devSections, 785 numDevSections, drv, &usedChips); 786 /* Free it since we don't need that list after this */ 787 xfree(devSections); 788 if (numUsed <= 0) 789 return FALSE; 790 791 792 if (flags & PROBE_DETECT) 793 foundScreen = TRUE; 794 else for (i = 0; i < numUsed; i++) { 795 ScrnInfoPtr pScrn = NULL; 796 EntityInfoPtr pEnt; 797 int attrib_no; 798#ifdef DISABLE_VGA_IO 799 MgaSavePtr smga; 800#endif 801 802 /* Allocate a ScrnInfoRec and claim the slot */ 803#ifndef DISABLE_VGA_IO 804 pScrn = xf86ConfigPciEntity(pScrn, 0,usedChips[i], 805 MGAPciChipsets, NULL, NULL, 806 NULL, NULL, NULL); 807#else 808 smga = xnfalloc(sizeof(MgaSave)); 809 smga->pvp = xf86GetPciInfoForEntity(usedChips[i]); 810 pScrn = xf86ConfigPciEntity(pScrn, 0,usedChips[i], 811 MGAPciChipsets, NULL,VgaIOSave, 812 VgaIOSave, VgaIORestore,smga); 813#endif 814 if (pScrn != NULL) { 815 MGAPtr pMga; 816 817 /* Fill in what we can of the ScrnInfoRec */ 818 pScrn->driverVersion = MGA_VERSION; 819 pScrn->driverName = MGA_DRIVER_NAME; 820 pScrn->name = MGA_NAME; 821 pScrn->Probe = MGAProbe; 822 pScrn->PreInit = MGAPreInit; 823 pScrn->ScreenInit = MGAScreenInit; 824 pScrn->SwitchMode = MGASwitchMode; 825 pScrn->AdjustFrame = MGAAdjustFrame; 826 pScrn->EnterVT = MGAEnterVT; 827 pScrn->LeaveVT = MGALeaveVT; 828 pScrn->FreeScreen = MGAFreeScreen; 829 pScrn->ValidMode = MGAValidMode; 830 831 foundScreen = TRUE; 832 833 /* Allocate the MGARec driverPrivate */ 834 if (!MGAGetRec(pScrn)) { 835 return FALSE; 836 } 837 838 pMga = MGAPTR(pScrn); 839 840 /* 841 * For cards that can do dual head per entity, mark the entity 842 * as sharable. 843 */ 844 pEnt = xf86GetEntityInfo(usedChips[i]); 845 846 switch (pEnt->chipset) { 847 case PCI_CHIP_MGA2064: 848 attrib_no = 0; 849 break; 850 851 case PCI_CHIP_MGA1064: 852 attrib_no = 1; 853 break; 854 855 case PCI_CHIP_MGA2164: 856 case PCI_CHIP_MGA2164_AGP: 857 attrib_no = 2; 858 break; 859 860 case PCI_CHIP_MGAG100: 861 case PCI_CHIP_MGAG100_PCI: 862 attrib_no = 3; 863 break; 864 865 case PCI_CHIP_MGAG200: 866 case PCI_CHIP_MGAG200_PCI: 867 attrib_no = 4; 868 break; 869 870 case PCI_CHIP_MGAG400: 871 attrib_no = 5; 872 break; 873 874 case PCI_CHIP_MGAG550: 875 attrib_no = 6; 876 break; 877 878 case PCI_CHIP_MGAG200_SE_A_PCI: 879 case PCI_CHIP_MGAG200_SE_B_PCI: 880 attrib_no = 7; 881 break; 882 883 default: 884 return FALSE; 885 } 886 887 pMga->chip_attribs = & attribs[attrib_no]; 888 889 if (pMga->chip_attribs->dual_head_possible) { 890 MGAEntPtr pMgaEnt = NULL; 891 DevUnion *pPriv; 892 893 xf86SetEntitySharable(usedChips[i]); 894 /* Allocate an entity private if necessary */ 895 if (MGAEntityIndex < 0) 896 MGAEntityIndex = xf86AllocateEntityPrivateIndex(); 897 pPriv = xf86GetEntityPrivate(pScrn->entityList[0], MGAEntityIndex); 898 if (!pPriv->ptr) { 899 pPriv->ptr = xnfcalloc(sizeof(MGAEntRec), 1); 900 pMgaEnt = pPriv->ptr; 901 pMgaEnt->lastInstance = -1; 902 } else { 903 pMgaEnt = pPriv->ptr; 904 } 905 /* 906 * Set the entity instance for this instance of the driver. For 907 * dual head per card, instance 0 is the "master" instance, driving 908 * the primary head, and instance 1 is the "slave". 909 */ 910 pMgaEnt->lastInstance++; 911 xf86SetEntityInstanceForScreen(pScrn, pScrn->entityList[0], 912 pMgaEnt->lastInstance); 913 } 914 } 915 } 916 xfree(usedChips); 917 918 return foundScreen; 919} 920#endif 921 922 923/* 924 * MGASoftReset -- 925 * 926 * Resets drawing engine 927 */ 928void 929MGASoftReset(ScrnInfoPtr pScrn) 930{ 931 MGAPtr pMga = MGAPTR(pScrn); 932 933 pMga->FbMapSize = 8192 * 1024; 934 MGAMapMem(pScrn); 935 936 /* set soft reset bit */ 937 OUTREG(MGAREG_Reset, 1); 938 usleep(200); 939 OUTREG(MGAREG_Reset, 0); 940 941 /* reset memory */ 942 OUTREG(MGAREG_MACCESS, 1<<15); 943 usleep(10); 944 945#if 0 946 /* This will hang if the PLLs aren't on */ 947 948 /* wait until drawing engine is ready */ 949 while ( MGAISBUSY() ) 950 usleep(1000); 951 952 /* flush FIFO */ 953 i = 32; 954 WAITFIFO(i); 955 while ( i-- ) 956 OUTREG(MGAREG_SHIFT, 0); 957#endif 958 959 MGAUnmapMem(pScrn); 960} 961 962/* 963 * MGACountRAM -- 964 * 965 * Counts amount of installed RAM 966 */ 967static int 968MGACountRam(ScrnInfoPtr pScrn) 969{ 970 MGAPtr pMga = MGAPTR(pScrn); 971 int ProbeSize = 8192; 972 int SizeFound = 2048; 973 CARD32 biosInfo = 0; 974 CARD8 seq1; 975 976#if 0 977 /* This isn't correct. It looks like this can have arbitrary 978 data for the memconfig even when the bios has initialized 979 it. At least, my cards don't advertise the documented 980 values (my 8 and 16 Meg G200s have the same values) */ 981 if (pMga->Primary) { /* can only trust this for primary cards */ 982#ifdef XSERVER_LIBPCIACCESS 983 pci_device_cfg_read_u32(pMga->PciInfo, & biosInfo, 984 PCI_OPTION_REG); 985#else 986 biosInfo = pciReadLong(pMga->PciTag, PCI_OPTION_REG); 987#endif 988 } 989#endif 990 991 switch(pMga->Chipset) { 992 case PCI_CHIP_MGA2164: 993 case PCI_CHIP_MGA2164_AGP: 994 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 995 "Unable to probe memory amount due to hardware bug. " 996 "Assuming 4096 KB\n"); 997 return 4096; 998 case PCI_CHIP_MGAG400: 999 case PCI_CHIP_MGAG550: 1000 if(biosInfo) { 1001 switch((biosInfo >> 10) & 0x07) { 1002 case 0: 1003 return (biosInfo & (1 << 14)) ? 32768 : 16384; 1004 case 1: 1005 case 2: 1006 return 16384; 1007 case 3: 1008 case 5: 1009 return 65536; 1010 case 4: 1011 return 32768; 1012 } 1013 } 1014 ProbeSize = 32768; 1015 break; 1016 case PCI_CHIP_MGAG200_SE_A_PCI: 1017 case PCI_CHIP_MGAG200_SE_B_PCI: 1018 ProbeSize = 4096; 1019 break; 1020 case PCI_CHIP_MGAG200: 1021 case PCI_CHIP_MGAG200_PCI: 1022 if(biosInfo) { 1023 switch((biosInfo >> 11) & 0x03) { 1024 case 0: 1025 return 8192; 1026 default: 1027 return 16384; 1028 } 1029 } 1030 ProbeSize = 8192; 1031 break; 1032 case PCI_CHIP_MGAG100: 1033 case PCI_CHIP_MGAG100_PCI: 1034 if(biosInfo) /* I'm not sure if the docs are correct */ 1035 return (biosInfo & (1 << 12)) ? 16384 : 8192; 1036 case PCI_CHIP_MGA1064: 1037 case PCI_CHIP_MGA2064: 1038 ProbeSize = 8192; 1039 break; 1040 default: 1041 break; 1042 } 1043 1044 if (pMga->FbAddress) { 1045 volatile unsigned char* base; 1046 unsigned char tmp; 1047 int i; 1048 1049 pMga->FbMapSize = ProbeSize * 1024; 1050 if (!MGAMapMem(pScrn)) { 1051 return 0; 1052 } 1053 1054 base = pMga->FbBase; 1055 1056 if (pMga->is_G200SE) { 1057 OUTREG8(MGAREG_SEQ_INDEX, 0x01); 1058 seq1 = INREG8(MGAREG_SEQ_DATA); 1059 seq1 |= 0x20; 1060 MGAWAITVSYNC(); 1061 MGAWAITBUSY(); 1062 OUTREG8(MGAREG_SEQ_DATA, seq1); 1063 usleep(20000); 1064 } 1065 1066 /* turn MGA mode on - enable linear frame buffer (CRTCEXT3) */ 1067 OUTREG8(MGAREG_CRTCEXT_INDEX, 3); 1068 tmp = INREG8(MGAREG_CRTCEXT_DATA); 1069 OUTREG8(MGAREG_CRTCEXT_DATA, tmp | 0x80); 1070 1071 /* apparently the G200SE doesn't have a BIOS to read */ 1072 if (pMga->is_G200SE) { 1073 CARD32 MemoryAt0, MemoryAt1, Offset; 1074 CARD32 FirstMemoryVal1, FirstMemoryVal2; 1075 CARD32 SecondMemoryVal1, SecondMemoryVal2; 1076 CARD32 TestMemoryLocA, TestMemoryLocB; 1077 CARD32 TestMemoryLoc0, TestMemoryLoc1; 1078 CARD32 TestA, TestB; 1079 1080 MemoryAt0 = base[0]; 1081 MemoryAt1 = base[1]; 1082 base[0] = 0; 1083 base[1] = 0; 1084 1085 for (Offset = 0x100000; Offset < (ProbeSize * 1024); 1086 Offset += 0x1000) { 1087 FirstMemoryVal1 = base[Offset]; 1088 FirstMemoryVal2 = base[Offset+1]; 1089 SecondMemoryVal1 = base[Offset+0x100]; 1090 SecondMemoryVal2 = base[Offset+0x101]; 1091 1092 base[Offset] = 0x55; 1093 base[Offset+1] = 0xaa; 1094 base[Offset+0x100] = 0x55; 1095 base[Offset+0x101] = 0xaa; 1096 1097 OUTREG(MGAREG_CRTC_INDEX, 0); 1098 usleep(8); 1099 1100 TestMemoryLocA = base[Offset]; 1101 TestMemoryLocB = base[Offset+1]; 1102 TestMemoryLoc0 = base[0]; 1103 TestMemoryLoc1 = base[1]; 1104 1105 base[Offset] = FirstMemoryVal1; 1106 base[Offset+1] = FirstMemoryVal2; 1107 base[Offset+0x100] = SecondMemoryVal1; 1108 base[Offset+0x101] = SecondMemoryVal2; 1109 1110 TestA = ((TestMemoryLocB << 8) + TestMemoryLocA); 1111 TestB = ((TestMemoryLoc1 << 8) + TestMemoryLoc0); 1112 if ((TestA != 0xAA55) || (TestB)) { 1113 break; 1114 } 1115 } 1116 1117 base[0] = MemoryAt0; 1118 base[1] = MemoryAt1; 1119 1120 SizeFound = (Offset / 1024) - 64; 1121 } else { 1122 /* write, read and compare method 1123 split into two loops to make it more reliable on RS/6k -ReneR */ 1124 for(i = ProbeSize; i > 2048; i -= 2048) { 1125 base[(i * 1024) - 1] = 0xAA; 1126 } 1127 OUTREG8(MGAREG_CRTC_INDEX, 0); /* flush the cache */ 1128 usleep(4); /* twart write combination */ 1129 for(i = ProbeSize; i > 2048; i -= 2048) { 1130 if(base[(i * 1024) - 1] == 0xAA) { 1131 SizeFound = i; 1132 break; 1133 } 1134 } 1135 } 1136 1137 /* restore CRTCEXT3 state */ 1138 OUTREG8(MGAREG_CRTCEXT_INDEX, 3); 1139 OUTREG8(MGAREG_CRTCEXT_DATA, tmp); 1140 1141 if (pMga->is_G200SE) { 1142 OUTREG8(MGAREG_SEQ_INDEX, 0x01); 1143 seq1 = INREG8(MGAREG_SEQ_DATA); 1144 seq1 &= ~0x20; 1145 MGAWAITVSYNC(); 1146 MGAWAITBUSY(); 1147 OUTREG8(MGAREG_SEQ_DATA, seq1); 1148 usleep(20000); 1149 } 1150 MGAUnmapMem(pScrn); 1151 } 1152 return SizeFound; 1153} 1154 1155static xf86MonPtr 1156MGAdoDDC(ScrnInfoPtr pScrn) 1157{ 1158 vgaHWPtr hwp; 1159 MGAPtr pMga; 1160 xf86MonPtr MonInfo = NULL; 1161 1162 hwp = VGAHWPTR(pScrn); 1163 pMga = MGAPTR(pScrn); 1164 1165 /* Load DDC if we have the code to use it */ 1166 /* This gives us DDC1 */ 1167 if (pMga->ddc1Read || pMga->i2cInit) { 1168 if (xf86LoadSubModule(pScrn, "ddc")) { 1169 xf86LoaderReqSymLists(ddcSymbols, NULL); 1170 } else { 1171 /* ddc module not found, we can do without it */ 1172 pMga->ddc1Read = NULL; 1173 pMga->DDC_Bus1 = NULL; 1174 pMga->DDC_Bus2 = NULL; 1175 return NULL; 1176 } 1177 } else 1178 return NULL; 1179 1180#if MGAuseI2C 1181 /* - DDC can use I2C bus */ 1182 /* Load I2C if we have the code to use it */ 1183 if (pMga->i2cInit) { 1184 if ( xf86LoadSubModule(pScrn, "i2c") ) { 1185 xf86LoaderReqSymLists(i2cSymbols,NULL); 1186 } else { 1187 /* i2c module not found, we can do without it */ 1188 pMga->i2cInit = NULL; 1189 pMga->DDC_Bus1 = NULL; 1190 pMga->DDC_Bus2 = NULL; 1191 } 1192 } 1193#endif /* MGAuseI2C */ 1194 1195 /* Map the MGA memory and MMIO areas */ 1196 if (!MGAMapMem(pScrn)) 1197 return NULL; 1198 1199 /* Initialise the MMIO vgahw functions */ 1200 vgaHWSetMmioFuncs(hwp, pMga->IOBase, PORT_OFFSET); 1201 vgaHWGetIOBase(hwp); 1202 1203 /* Map the VGA memory when the primary video */ 1204 if (pMga->Primary) { 1205 hwp->MapSize = 0x10000; 1206 if (!vgaHWMapMem(pScrn)) 1207 return NULL; 1208 } else { 1209 /* XXX Need to write an MGA mode ddc1SetSpeed */ 1210 if (pMga->DDC1SetSpeed == vgaHWddc1SetSpeedWeak()) { 1211 pMga->DDC1SetSpeed = NULL; 1212 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, 1213 "DDC1 disabled - chip not in VGA mode\n"); 1214 } 1215 } 1216 1217 /* Save the current state */ 1218 MGASave(pScrn); 1219 1220 /* It is now safe to talk to the card */ 1221 1222#if MGAuseI2C 1223 /* Initialize I2C buses - used by DDC if available */ 1224 if (pMga->i2cInit) { 1225 pMga->i2cInit(pScrn); 1226 } 1227 1228 /* DDC for second head... */ 1229 if (pMga->SecondCrtc && pMga->DDC_Bus2) { 1230 MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex,pMga->DDC_Bus2); 1231 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "I2C Monitor info: %p\n", 1232 (void *)MonInfo); 1233 xf86PrintEDID(MonInfo); 1234 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of I2C Monitor info\n"); 1235 xf86SetDDCproperties(pScrn, MonInfo); 1236 return MonInfo; 1237 } 1238 1239 else { 1240 /* Its the first head... */ 1241 if (pMga->DDC_Bus1) { 1242 MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex,pMga->DDC_Bus1); 1243 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "I2C Monitor info: %p\n", (void *) MonInfo); 1244 xf86PrintEDID(MonInfo); 1245 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of I2C Monitor info\n"); 1246 } 1247 if (!MonInfo) 1248#endif /* MGAuseI2C */ 1249 /* Read and output monitor info using DDC1 */ 1250 if (pMga->ddc1Read && pMga->DDC1SetSpeed) { 1251 MonInfo = xf86DoEDID_DDC1(pScrn->scrnIndex, 1252 pMga->DDC1SetSpeed, 1253 pMga->ddc1Read ) ; 1254 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC Monitor info: %p\n", (void *) MonInfo); 1255 xf86PrintEDID( MonInfo ); 1256 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of DDC Monitor info\n"); 1257 } 1258 if (!MonInfo){ 1259 vbeInfoPtr pVbe; 1260 if (xf86LoadSubModule(pScrn, "vbe")) { 1261 pVbe = VBEInit(NULL,pMga->pEnt->index); 1262 MonInfo = vbeDoEDID(pVbe, NULL); 1263 vbeFree(pVbe); 1264 1265 if (MonInfo){ 1266 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VBE DDC Monitor info: %p\n", (void *) MonInfo); 1267 xf86PrintEDID( MonInfo ); 1268 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of VBE DDC Monitor info\n\n"); 1269 } 1270 } 1271 } 1272#if MGAuseI2C 1273 } 1274#endif 1275 /* Restore previous state and unmap MGA memory and MMIO areas */ 1276 MGARestore(pScrn); 1277 MGAUnmapMem(pScrn); 1278 /* Unmap vga memory if we mapped it */ 1279 if (xf86IsPrimaryPci(pMga->PciInfo) && !pMga->FBDev) { 1280 vgaHWUnmapMem(pScrn); 1281 } 1282 1283 xf86SetDDCproperties(pScrn, MonInfo); 1284 1285 return MonInfo; 1286} 1287 1288#ifdef DISABLE_VGA_IO 1289static void 1290VgaIOSave(int i, void *arg) 1291{ 1292 MgaSavePtr sMga = arg; 1293#ifndef XSERVER_LIBPCIACCESS 1294 PCITAG tag = pciTag(sMga->pvp->bus,sMga->pvp->device,sMga->pvp->func); 1295#endif 1296 uint32_t temp; 1297 1298#ifdef DEBUG 1299 ErrorF("mga: VgaIOSave: %d:%d:%d\n", sMga->pvp->bus, sMga->pvp->device, 1300 sMga->pvp->func); 1301#endif 1302#ifdef XSERVER_LIBPCIACCESS 1303 pci_device_cfg_read_u32(pMga->PciInfo, & temp, PCI_OPTION_REG); 1304#else 1305 temp = pciReadLong(tag, PCI_OPTION_REG); 1306#endif 1307 sMga->enable = (temp & 0x100) != 0; 1308} 1309 1310static void 1311VgaIORestore(int i, void *arg) 1312{ 1313 MgaSavePtr sMga = arg; 1314#ifndef XSERVER_LIBPCIACCESS 1315 PCITAG tag = pciTag(sMga->pvp->bus,sMga->pvp->device,sMga->pvp->func); 1316#endif 1317 1318#ifdef DEBUG 1319 ErrorF("mga: VgaIORestore: %d:%d:%d\n", sMga->pvp->bus, sMga->pvp->device, 1320 sMga->pvp->func); 1321#endif 1322#ifdef XSERVER_LIBPCIACCESS 1323 pci_device_cfg_write_bits(pMga->PciInfo, 0x00000100, sMga->enable, 1324 PCI_OPTION_REG); 1325#else 1326 pciSetBitsLong(tag, PCI_OPTION_REG, 0x100, sMga->enable ? 0x100 : 0x000); 1327#endif 1328} 1329 1330static void 1331VgaIODisable(void *arg) 1332{ 1333 MGAPtr pMga = arg; 1334 1335#ifdef DEBUG 1336 ErrorF("mga: VgaIODisable: %d:%d:%d, %s, xf86ResAccessEnter is %s\n", 1337 pMga->PciInfo->bus, pMga->PciInfo->device, pMga->PciInfo->func, 1338 pMga->Primary ? "primary" : "secondary", 1339 BOOLTOSTRING(xf86ResAccessEnter)); 1340#endif 1341 /* Turn off the vgaioen bit. */ 1342#ifdef XSERVER_LIBPCIACCESS 1343 pci_device_cfg_write_bits(pMga->PciInfo, 0x00000100, 0x00000000, 1344 PCI_OPTION_REG); 1345#else 1346 pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, 0x100, 0x000); 1347#endif 1348} 1349 1350static void 1351VgaIOEnable(void *arg) 1352{ 1353 MGAPtr pMga = arg; 1354 1355#ifdef DEBUG 1356 ErrorF("mga: VgaIOEnable: %d:%d:%d, %s, xf86ResAccessEnter is %s\n", 1357 pMga->PciInfo->bus, pMga->PciInfo->device, pMga->PciInfo->func, 1358 pMga->Primary ? "primary" : "secondary", 1359 BOOLTOSTRING(xf86ResAccessEnter)); 1360#endif 1361 /* Turn on the vgaioen bit. */ 1362 if (pMga->Primary) { 1363#ifdef XSERVER_LIBPCIACCESS 1364 pci_device_cfg_write_bits(pMga->PciInfo, 0x00000100, 0x00000100, 1365 PCI_OPTION_REG); 1366#else 1367 pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, 0x100, 0x100); 1368#endif 1369 } 1370} 1371#endif /* DISABLE_VGA_IO */ 1372 1373void 1374MGAProbeDDC(ScrnInfoPtr pScrn, int index) 1375{ 1376 vbeInfoPtr pVbe; 1377 if (xf86LoadSubModule(pScrn, "vbe")) { 1378 pVbe = VBEInit(NULL,index); 1379 ConfiguredMonitor = vbeDoEDID(pVbe, NULL); 1380 vbeFree(pVbe); 1381 } 1382} 1383 1384Bool 1385MGAMavenRead(ScrnInfoPtr pScrn, I2CByte reg, I2CByte *val) 1386{ 1387 MGAPtr pMga = MGAPTR(pScrn); 1388 1389 if (!pMga->Maven) return FALSE; 1390 1391 /* FIXME: Using private interfaces for the moment until a more 1392 * flexible xf86I2CWriteRead() variant shows up for us 1393 * 1394 * MAVEN does _not_ like a start bit in the middle of its transaction 1395 * MAVEN does _not_ like ACK at the end of the transaction 1396 */ 1397 1398 if (!pMga->Maven_Bus->I2CStart(pMga->Maven_Bus, pMga->Maven->ByteTimeout)) return FALSE; 1399 if (!pMga->Maven_Bus->I2CPutByte(pMga->Maven, MAVEN_READ)) return FALSE; 1400 if (!pMga->Maven_Bus->I2CPutByte(pMga->Maven, reg)) return FALSE; 1401 pMga->Maven_Bus->I2CStop(pMga->Maven); 1402 if (!pMga->Maven_Bus->I2CGetByte(pMga->Maven, val, 0)) return FALSE; 1403 pMga->Maven_Bus->I2CStop(pMga->Maven); 1404 1405 return TRUE; 1406} 1407 1408/* Mandatory */ 1409static Bool 1410MGAPreInit(ScrnInfoPtr pScrn, int flags) 1411{ 1412 MGAPtr pMga; 1413 MessageType from; 1414 int i; 1415 double real; 1416 int bytesPerPixel; 1417 ClockRangePtr clockRanges; 1418 const char *s; 1419 int flags24; 1420 MGAEntPtr pMgaEnt = NULL; 1421 Bool Default; 1422#ifdef USEMGAHAL 1423 ULONG status; 1424 CARD8 MiscCtlReg; 1425#endif 1426 1427 /* 1428 * Note: This function is only called once at server startup, and 1429 * not at the start of each server generation. This means that 1430 * only things that are persistent across server generations can 1431 * be initialised here. xf86Screens[] is (pScrn is a pointer to one 1432 * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex() 1433 * are too, and should be used for data that must persist across 1434 * server generations. 1435 * 1436 * Per-generation data should be allocated with 1437 * AllocateScreenPrivateIndex() from the ScreenInit() function. 1438 */ 1439 1440 /* Check the number of entities, and fail if it isn't one. */ 1441 if (pScrn->numEntities != 1) 1442 return FALSE; 1443 1444 1445 pMga = MGAPTR(pScrn); 1446 /* Set here until dri is enabled */ 1447#ifdef XF86DRI 1448 pMga->haveQuiescense = 1; 1449#endif 1450 /* Get the entity, and make sure it is PCI. */ 1451 pMga->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 1452 if (pMga->pEnt->location.type != BUS_PCI) 1453 return FALSE; 1454 1455 /* Allocate an entity private if necessary */ 1456 if (xf86IsEntityShared(pScrn->entityList[0])) { 1457 pMgaEnt = xf86GetEntityPrivate(pScrn->entityList[0], 1458 MGAEntityIndex)->ptr; 1459 pMga->entityPrivate = pMgaEnt; 1460 } 1461 1462 /* Set pMga->device to the relevant Device section */ 1463 pMga->device = xf86GetDevFromEntity(pScrn->entityList[0], 1464 pScrn->entityInstanceList[0]); 1465 1466 if (flags & PROBE_DETECT) { 1467 MGAProbeDDC(pScrn, pMga->pEnt->index); 1468 return TRUE; 1469 } 1470 1471 /* The vgahw module should be loaded here when needed */ 1472 if (!xf86LoadSubModule(pScrn, "vgahw")) 1473 return FALSE; 1474 1475 xf86LoaderReqSymLists(vgahwSymbols, NULL); 1476 1477 /* 1478 * Allocate a vgaHWRec 1479 */ 1480 if (!vgaHWGetHWRec(pScrn)) 1481 return FALSE; 1482 1483#ifndef XSERVER_LIBPCIACCESS 1484 /* Find the PCI info for this screen */ 1485 pMga->PciInfo = xf86GetPciInfoForEntity(pMga->pEnt->index); 1486 pMga->PciTag = pciTag(pMga->PciInfo->bus, pMga->PciInfo->device, 1487 pMga->PciInfo->func); 1488#endif 1489 1490 pMga->Primary = xf86IsPrimaryPci(pMga->PciInfo); 1491 1492#ifndef DISABLE_VGA_IO 1493 xf86SetOperatingState(resVgaIo, pMga->pEnt->index, ResUnusedOpr); 1494 xf86SetOperatingState(resVgaMem, pMga->pEnt->index, ResDisableOpr); 1495#else 1496 /* 1497 * Set our own access functions, which control the vgaioen bit. 1498 */ 1499 pMga->Access.AccessDisable = VgaIODisable; 1500 pMga->Access.AccessEnable = VgaIOEnable; 1501 pMga->Access.arg = pMga; 1502 xf86SetAccessFuncs(pMga->pEnt, &pMga->Access, &pMga->Access); 1503#endif 1504 1505 /* Set pScrn->monitor */ 1506 pScrn->monitor = pScrn->confScreen->monitor; 1507 1508 /* 1509 * Set the Chipset and ChipRev, allowing config file entries to 1510 * override. 1511 */ 1512 if (pMga->device->chipset && *pMga->device->chipset) { 1513 pScrn->chipset = pMga->device->chipset; 1514 pMga->Chipset = xf86StringToToken(MGAChipsets, pScrn->chipset); 1515 from = X_CONFIG; 1516 } else if (pMga->device->chipID >= 0) { 1517 pMga->Chipset = pMga->device->chipID; 1518 pScrn->chipset = (char *)xf86TokenToString(MGAChipsets, pMga->Chipset); 1519 from = X_CONFIG; 1520 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", 1521 pMga->Chipset); 1522 } else { 1523 from = X_PROBED; 1524 pMga->Chipset = DEVICE_ID(pMga->PciInfo); 1525 pScrn->chipset = (char *)xf86TokenToString(MGAChipsets, pMga->Chipset); 1526 } 1527 1528 if (pMga->device->chipRev >= 0) { 1529 pMga->ChipRev = pMga->device->chipRev; 1530 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", 1531 pMga->ChipRev); 1532 } else { 1533 pMga->ChipRev = CHIP_REVISION(pMga->PciInfo); 1534 } 1535 1536 /* 1537 * This shouldn't happen because such problems should be caught in 1538 * MGAProbe(), but check it just in case. 1539 */ 1540 if (pScrn->chipset == NULL) { 1541 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1542 "ChipID 0x%04X is not recognised\n", pMga->Chipset); 1543 return FALSE; 1544 } 1545 if (pMga->Chipset < 0) { 1546 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1547 "Chipset \"%s\" is not recognised\n", pScrn->chipset); 1548 return FALSE; 1549 } 1550 1551 xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"", pScrn->chipset); 1552 if (pMga->Chipset == PCI_CHIP_MGAG400) { 1553 if (pMga->ChipRev >= 0x80) 1554 xf86ErrorF(" (G450)\n"); 1555 else 1556 xf86ErrorF(" (G400)\n"); 1557 } else { 1558 xf86ErrorF("\n"); 1559 } 1560 1561 pMga->is_Gx50 = ((pMga->Chipset == PCI_CHIP_MGAG400) && (pMga->ChipRev >= 0x80)) 1562 || (pMga->Chipset == PCI_CHIP_MGAG550); 1563 pMga->is_G200SE = (pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) 1564 || (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI); 1565 1566#ifdef USEMGAHAL 1567 if (pMga->chip_attribs->HAL_chipset) { 1568 Bool loadHal = TRUE; 1569 1570 from = X_DEFAULT; 1571 if (xf86FindOption(pMga->device->options, "NoHal")) { 1572 loadHal = !xf86SetBoolOption(pMga->device->options, 1573 "NoHal", !loadHal); 1574 from = X_CONFIG; 1575 } else if (xf86FindOption(pMga->device->options, "Hal")) { 1576 loadHal = xf86SetBoolOption(pMga->device->options, 1577 "Hal", loadHal); 1578 from = X_CONFIG; 1579 } 1580 if (loadHal && xf86LoadSubModule(pScrn, "mga_hal")) { 1581 xf86LoaderReqSymLists(halSymbols, NULL); 1582 xf86DrvMsg(pScrn->scrnIndex, from,"Matrox HAL module used\n"); 1583 pMga->HALLoaded = TRUE; 1584 } else { 1585 xf86DrvMsg(pScrn->scrnIndex, from, "Matrox HAL module not loaded " 1586 "- using builtin mode setup instead\n"); 1587 pMga->HALLoaded = FALSE; 1588 } 1589 } 1590#endif 1591 1592 pMga->DualHeadEnabled = FALSE; 1593 if (xf86IsEntityShared(pScrn->entityList[0])) {/* dual-head mode requested*/ 1594 if ( 1595#ifdef USEMGAHAL 1596 pMga->HALLoaded || 1597#endif 1598 !MGA_DH_NEEDS_HAL(pMga)) { 1599 pMga->DualHeadEnabled = TRUE; 1600 } else if (xf86IsPrimInitDone(pScrn->entityList[0])) { 1601 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1602 "This card requires the \"mga_hal\" module for dual-head operation\n" 1603 "\tIt can be found at the Matrox web site <http://www.matrox.com>\n"); 1604 } 1605 } 1606 1607 /* 1608 * In case of DualHead, we need to determine if we are the 'master' head 1609 * or the 'slave' head. In order to do that, at the end of the first 1610 * initialisation, PrimInit is set as DONE to the shared entity. So that 1611 * the second initialisation knows that something has been done before it. 1612 * This always assume that the first device initialised is the master 1613 * head, and the second the slave. 1614 * 1615 */ 1616 if (xf86IsEntityShared(pScrn->entityList[0])) { /* dual-head mode */ 1617 if (!xf86IsPrimInitDone(pScrn->entityList[0])) { /* Is it the first initialisation? */ 1618 /* First CRTC */ 1619 pMga->SecondCrtc = FALSE; 1620 pMga->HWCursor = TRUE; 1621 pMgaEnt->pScrn_1 = pScrn; 1622 } else if (pMga->DualHeadEnabled) { 1623 /* Second CRTC */ 1624 pMga->SecondCrtc = TRUE; 1625 pMga->HWCursor = FALSE; 1626 pMgaEnt->pScrn_2 = pScrn; 1627 pScrn->AdjustFrame = MGAAdjustFrameCrtc2; 1628 /* 1629 * Fail initialization of second head if we are in MergeFB mode, 1630 * since we do it ourselfs. 1631 */ 1632 if(pMgaEnt->pScrn_1 && MGAPTR(pMgaEnt->pScrn_1)->MergedFB) { 1633 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1634 "Primary head in Merged framebuffer mode. \n" 1635 "Don't let Xfree try to manage the second head.\n" 1636 "Remove the second screen in the \"ServerLayout\"\n" 1637 "Section of the config file."); 1638 return FALSE; 1639 } 1640 } else { 1641 return FALSE; 1642 } 1643 } 1644 1645 if (pMga->DualHeadEnabled) { 1646#ifdef XF86DRI 1647 pMga->GetQuiescence = MGAGetQuiescenceShared; 1648#endif 1649 } else { /* single-head mode */ 1650 pMga->SecondCrtc = FALSE; 1651 pMga->HWCursor = TRUE; 1652#ifdef XF86DRI 1653 pMga->GetQuiescence = MGAGetQuiescence; 1654#endif 1655 } 1656 1657 1658 1659 /* 1660 * The first thing we should figure out is the depth, bpp, etc. 1661 * Our default depth is 8, so pass it to the helper function. 1662 * We support both 24bpp and 32bpp layouts, so indicate that. 1663 */ 1664 1665 /* Prefer 24bpp fb unless the Overlay option is set, or DRI is 1666 * supported. 1667 */ 1668 flags24 = Support24bppFb | Support32bppFb | SupportConvert32to24; 1669 s = xf86TokenToOptName(MGAOptions, OPTION_OVERLAY); 1670#ifndef XF86DRI 1671 if (!(xf86FindOption(pScrn->confScreen->options, s) || 1672 xf86FindOption(pMga->device->options, s))) { 1673 flags24 |= PreferConvert32to24; 1674 } 1675#endif 1676 1677 if (pMga->SecondCrtc) 1678 flags24 = Support32bppFb; 1679 1680 if (pMga->is_G200SE) 1681 pScrn->confScreen->defaultdepth = 16; 1682 1683 if (!xf86SetDepthBpp(pScrn, 0, 0, 0, flags24)) { 1684 return FALSE; 1685 } else { 1686 /* Check that the returned depth is one we support */ 1687 switch (pScrn->depth) { 1688 case 8: 1689 case 15: 1690 case 16: 1691 case 24: 1692 /* OK */ 1693 break; 1694 default: 1695 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1696 "Given depth (%d) is not supported by this driver\n", 1697 pScrn->depth); 1698 return FALSE; 1699 } 1700 } 1701 xf86PrintDepthBpp(pScrn); 1702 1703 /* 1704 * This must happen after pScrn->display has been set because 1705 * xf86SetWeight references it. 1706 */ 1707 if (pScrn->depth > 8) { 1708 /* The defaults are OK for us */ 1709 rgb zeros = {0, 0, 0}; 1710 1711 if (!xf86SetWeight(pScrn, zeros, zeros)) { 1712 return FALSE; 1713 } else { 1714 /* XXX check that weight returned is supported */ 1715 ; 1716 } 1717 } 1718 1719 bytesPerPixel = pScrn->bitsPerPixel / 8; 1720 1721 /* We use a programmable clock */ 1722 pScrn->progClock = TRUE; 1723 1724 /* Collect all of the relevant option flags (fill in pScrn->options) */ 1725 xf86CollectOptions(pScrn, NULL); 1726 1727 /* Process the options */ 1728 if (!(pMga->Options = xalloc(sizeof(MGAOptions)))) 1729 return FALSE; 1730 memcpy(pMga->Options, MGAOptions, sizeof(MGAOptions)); 1731 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pMga->Options); 1732 1733 if (pMga->is_G200SE) { 1734 /* Disable MTRR support on PCIe systems */ 1735#ifdef XSERVER_LIBPCIACCESS 1736 uint32_t temp; 1737 1738 pci_device_cfg_read_u32(pMga->PciInfo, & temp, 0xDC); 1739#else 1740 CARD32 temp = pciReadLong(pMga->PciTag, 0xDC); 1741#endif 1742 1743 if ((temp & 0x0000FF00) != 0x0) { 1744 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling MTRR support.\n"); 1745 pScrn->options = xf86ReplaceBoolOption(pScrn->options, "MTRR", FALSE); 1746 } 1747 } 1748 1749#if !defined(__powerpc__) 1750 pMga->softbooted = FALSE; 1751 Default = (pMga->chip_attribs->dual_head_possible 1752 && !pMga->Primary && !pMga->SecondCrtc); 1753 1754 if (xf86ReturnOptValBool(pMga->Options, OPTION_INT10, Default) && 1755 xf86LoadSubModule(pScrn, "int10")) { 1756 xf86Int10InfoPtr pInt; 1757 1758 xf86LoaderReqSymLists(int10Symbols, NULL); 1759 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n"); 1760 pInt = xf86InitInt10(pMga->pEnt->index); 1761 if (pInt) pMga->softbooted = TRUE; 1762 xf86FreeInt10(pInt); 1763 } 1764#endif 1765 1766 /* Set the bits per RGB for 8bpp mode */ 1767 if (pScrn->depth == 8) 1768 pScrn->rgbBits = 8; 1769 1770#ifdef XF86DRI 1771 from = X_DEFAULT; 1772 pMga->agpMode = MGA_DEFAULT_AGP_MODE; 1773 1774 if (xf86GetOptValInteger(pMga->Options, 1775 OPTION_AGP_MODE, &(pMga->agpMode))) { 1776 if (pMga->agpMode < 1) { 1777 pMga->agpMode = 1; 1778 } 1779 if (pMga->agpMode > MGA_MAX_AGP_MODE) { 1780 pMga->agpMode = MGA_MAX_AGP_MODE; 1781 } 1782 from = X_CONFIG; 1783 } 1784 if (xf86GetOptValInteger(pMga->Options, 1785 OPTION_AGP_SIZE, &(pMga->agpSize))) { 1786 /* check later */ 1787 xf86DrvMsg(pScrn->scrnIndex, from, "Using %d MB of AGP memory\n", 1788 pMga->agpSize); 1789 } 1790 1791 xf86DrvMsg(pScrn->scrnIndex, from, "Using AGP %dx mode\n", 1792 pMga->agpMode); 1793 1794 if (xf86ReturnOptValBool(pMga->Options, OPTION_OLDDMA, FALSE)) { 1795 pMga->useOldDmaInit = TRUE; 1796 } 1797 1798 if (xf86ReturnOptValBool(pMga->Options, OPTION_PCIDMA, FALSE)) { 1799 pMga->forcePciDma = TRUE; 1800 } 1801#endif 1802 1803 from = X_DEFAULT; 1804 1805 /* 1806 * The preferred method is to use the "hw cursor" option as a tri-state 1807 * option, with the default set above. 1808 */ 1809 if (xf86GetOptValBool(pMga->Options, OPTION_HW_CURSOR, &pMga->HWCursor)) { 1810 from = X_CONFIG; 1811 } 1812 1813 /* For compatibility, accept this too (as an override) */ 1814 if (xf86ReturnOptValBool(pMga->Options, OPTION_NOACCEL, FALSE)) { 1815 pMga->NoAccel = TRUE; 1816 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); 1817 } else { 1818 int from = X_DEFAULT; 1819#ifdef USE_EXA 1820 char *s = xf86GetOptValString(pMga->Options, OPTION_ACCELMETHOD); 1821#endif 1822 pMga->NoAccel = FALSE; 1823 pMga->Exa = FALSE; 1824#ifdef USE_EXA 1825 if (!xf86NameCmp(s, "EXA")) { 1826 pMga->Exa = TRUE; 1827 from = X_CONFIG; 1828 } 1829#endif 1830 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration\n", 1831 pMga->Exa ? "EXA" : "XAA"); 1832 } 1833 if (xf86ReturnOptValBool(pMga->Options, OPTION_PCI_RETRY, FALSE)) { 1834 pMga->UsePCIRetry = TRUE; 1835 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n"); 1836 } 1837 if (xf86ReturnOptValBool(pMga->Options, OPTION_SYNC_ON_GREEN, FALSE)) { 1838 pMga->SyncOnGreen = TRUE; 1839 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Sync-on-Green enabled\n"); 1840 } 1841 if (xf86ReturnOptValBool(pMga->Options, OPTION_SHOWCACHE, FALSE)) { 1842 pMga->ShowCache = TRUE; 1843 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShowCache enabled\n"); 1844 } 1845 if (xf86ReturnOptValBool(pMga->Options, OPTION_MGA_SDRAM, FALSE)) { 1846 pMga->HasSDRAM = TRUE; 1847 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Has SDRAM\n"); 1848 } 1849 if (xf86GetOptValFreq(pMga->Options, OPTION_SET_MCLK, OPTUNITS_MHZ, &real)) { 1850 pMga->MemClk = (int)(real * 1000.0); 1851 } 1852 if ((s = xf86GetOptValString(pMga->Options, OPTION_OVERLAY))) { 1853 if (!*s || !xf86NameCmp(s, "8,24") || !xf86NameCmp(s, "24,8")) { 1854 if(pScrn->bitsPerPixel == 32 && pMga->SecondCrtc == FALSE) { 1855 pMga->Overlay8Plus24 = TRUE; 1856 if(!xf86GetOptValInteger( 1857 pMga->Options, OPTION_COLOR_KEY,&(pMga->colorKey))) 1858 pMga->colorKey = TRANSPARENCY_KEY; 1859 pScrn->colorKey = pMga->colorKey; 1860 pScrn->overlayFlags = OVERLAY_8_32_PLANAR; 1861 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1862 "PseudoColor overlay enabled\n"); 1863 } else { 1864 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1865 "Option \"Overlay\" is only supported in 32 bits per pixel on" 1866 "the first CRTC\n"); 1867 } 1868 } else { 1869 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1870 "\"%s\" is not a valid value for Option \"Overlay\"\n", s); 1871 } 1872 } 1873 1874 if(xf86GetOptValInteger(pMga->Options, OPTION_VIDEO_KEY, &(pMga->videoKey))) { 1875 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n", 1876 pMga->videoKey); 1877 } else { 1878 pMga->videoKey = (1 << pScrn->offset.red) | 1879 (1 << pScrn->offset.green) | 1880 (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << pScrn->offset.blue); 1881 } 1882 if (xf86ReturnOptValBool(pMga->Options, OPTION_SHADOW_FB, FALSE)) { 1883 pMga->ShadowFB = TRUE; 1884 pMga->NoAccel = TRUE; 1885 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1886 "Using \"Shadow Framebuffer\" - acceleration disabled\n"); 1887 } 1888 if (xf86ReturnOptValBool(pMga->Options, OPTION_FBDEV, FALSE)) { 1889 pMga->FBDev = TRUE; 1890 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1891 "Using framebuffer device\n"); 1892 } 1893 if (xf86ReturnOptValBool(pMga->Options, OPTION_OVERCLOCK_MEM, FALSE)) { 1894 pMga->OverclockMem = TRUE; 1895 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Overclocking memory\n"); 1896 } 1897 if (xf86ReturnOptValBool(pMga->Options, OPTION_TEXTURED_VIDEO, FALSE)) { 1898 pMga->TexturedVideo = TRUE; 1899 } 1900 if (xf86ReturnOptValBool(pMga->Options, OPTION_MERGEDFB, FALSE)) { 1901 if(!MGAISGx50(pMga)) { 1902 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1903 "\"Merged Framebuffer\" mode only supported on G450 and G550 boards.\n"); 1904 } else { 1905#ifdef USEMGAHAL 1906 if(pMga->HALLoaded) 1907 { 1908 pMga->MergedFB = TRUE; 1909 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1910 "Using \"Merged Framebuffer\" mode.\n"); 1911 /* 1912 * a few options that won't work well together 1913 */ 1914 if(pMga->HWCursor) /*Should we give the choice? */ 1915 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1916 " -- Hardware Cursor disabled.\n"); 1917 pMga->HWCursor = FALSE; 1918 if(pMga->ShadowFB) 1919 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1920 " -- Shadow Framebuffer disabled.\n"); 1921 pMga->ShadowFB = FALSE; 1922 if(pMga->FBDev) 1923 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1924 " -- Framebuffer device disabled.\n"); 1925 pMga->FBDev = FALSE; 1926 } /* MGA_HAL */ 1927 else 1928#endif 1929 { 1930 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1931 "HALLib not loaded! NOT using \"Merged Framebuffer\" mode.\n"); 1932 } /* MGA_NOT_HAL */ 1933 } /* ISMGAGx50() */ 1934 } 1935 if (pMga->FBDev) { 1936 /* check for linux framebuffer device */ 1937 if (!xf86LoadSubModule(pScrn, "fbdevhw")) 1938 return FALSE; 1939 xf86LoaderReqSymLists(fbdevHWSymbols, NULL); 1940 if (!fbdevHWInit(pScrn, pMga->PciInfo, NULL)) 1941 return FALSE; 1942 pScrn->SwitchMode = fbdevHWSwitchModeWeak(); 1943 pScrn->AdjustFrame = fbdevHWAdjustFrameWeak(); 1944 pScrn->EnterVT = MGAEnterVTFBDev; 1945 pScrn->LeaveVT = fbdevHWLeaveVTWeak(); 1946 pScrn->ValidMode = fbdevHWValidModeWeak(); 1947 } 1948 pMga->Rotate = 0; 1949 if ((s = xf86GetOptValString(pMga->Options, OPTION_ROTATE))) { 1950 if(!pMga->MergedFB) { 1951 if(!xf86NameCmp(s, "CW")) { 1952 pMga->ShadowFB = TRUE; 1953 pMga->NoAccel = TRUE; 1954 pMga->HWCursor = FALSE; 1955 pMga->Rotate = 1; 1956 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1957 "Rotating screen clockwise - acceleration disabled\n"); 1958 } else 1959 if(!xf86NameCmp(s, "CCW")) { 1960 pMga->ShadowFB = TRUE; 1961 pMga->NoAccel = TRUE; 1962 pMga->HWCursor = FALSE; 1963 pMga->Rotate = -1; 1964 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1965 "Rotating screen counter clockwise - acceleration disabled\n"); 1966 } else { 1967 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 1968 "\"%s\" is not a valid value for Option \"Rotate\"\n", s); 1969 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1970 "Valid options are \"CW\" or \"CCW\"\n"); 1971 } 1972 } else { 1973 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1974 " -- Rotation disabled.\n"); 1975 } 1976 } 1977 1978 switch (pMga->Chipset) { 1979 case PCI_CHIP_MGA2064: 1980 case PCI_CHIP_MGA2164: 1981 case PCI_CHIP_MGA2164_AGP: 1982 MGA2064SetupFuncs(pScrn); 1983 break; 1984 case PCI_CHIP_MGA1064: 1985 case PCI_CHIP_MGAG100: 1986 case PCI_CHIP_MGAG100_PCI: 1987 case PCI_CHIP_MGAG200: 1988 case PCI_CHIP_MGAG200_PCI: 1989 case PCI_CHIP_MGAG200_SE_A_PCI: 1990 case PCI_CHIP_MGAG200_SE_B_PCI: 1991 case PCI_CHIP_MGAG400: 1992 case PCI_CHIP_MGAG550: 1993 MGAGSetupFuncs(pScrn); 1994 break; 1995 } 1996 1997 /* ajv changes to reflect actual values. see sdk pp 3-2. */ 1998 /* these masks just get rid of the crap in the lower bits */ 1999 2000 /* For the 2064 and older rev 1064, base0 is the MMIO and base1 is 2001 * the framebuffer. 2002 */ 2003 2004 switch (pMga->chip_attribs->BARs) { 2005 case old_BARs: 2006 pMga->framebuffer_bar = 1; 2007 pMga->io_bar = 0; 2008 pMga->iload_bar = -1; 2009 break; 2010 case probe_BARs: 2011 if (pMga->ChipRev < 3) { 2012 pMga->framebuffer_bar = 1; 2013 pMga->io_bar = 0; 2014 pMga->iload_bar = 2; 2015 break; 2016 } 2017 /* FALLTHROUGH */ 2018 case new_BARs: 2019 pMga->framebuffer_bar = 0; 2020 pMga->io_bar = 1; 2021 pMga->iload_bar = 2; 2022 break; 2023 } 2024 2025 2026#ifdef XSERVER_LIBPCIACCESS 2027 pMga->FbAddress = pMga->PciInfo->regions[pMga->framebuffer_bar].base_addr; 2028#else 2029 pMga->FbAddress = pMga->PciInfo->memBase[pMga->framebuffer_bar] & 0xff800000; 2030#endif 2031 2032 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Linear framebuffer at 0x%lX\n", 2033 (unsigned long)pMga->FbAddress); 2034 2035#ifdef XSERVER_LIBPCIACCESS 2036 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "MMIO registers at 0x%lX\n", 2037 (unsigned long) pMga->PciInfo->regions[pMga->io_bar].base_addr); 2038#else 2039 pMga->IOAddress = pMga->PciInfo->memBase[pMga->io_bar] & 0xffffc000; 2040 2041 xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n", 2042 (unsigned long)pMga->IOAddress); 2043#endif 2044 2045 if (pMga->iload_bar != -1) { 2046#ifdef XSERVER_LIBPCIACCESS 2047 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2048 "Pseudo-DMA transfer window at 0x%lX\n", 2049 (unsigned long) pMga->PciInfo->regions[pMga->iload_bar].base_addr); 2050#else 2051 if (pMga->PciInfo->memBase[2] != 0) { 2052 pMga->ILOADAddress = pMga->PciInfo->memBase[2] & 0xffffc000; 2053 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2054 "Pseudo-DMA transfer window at 0x%lX\n", 2055 (unsigned long)pMga->ILOADAddress); 2056 } 2057#endif 2058 } 2059 2060 2061#ifndef XSERVER_LIBPCIACCESS 2062 /* 2063 * Find the BIOS base. Get it from the PCI config if possible. Otherwise 2064 * use the VGA default. Allow the config file to override this. 2065 */ 2066 2067 pMga->BiosFrom = X_NONE; 2068 if (pMga->device->BiosBase != 0) { 2069 /* XXX This isn't used */ 2070 pMga->BiosAddress = pMga->device->BiosBase; 2071 pMga->BiosFrom = X_CONFIG; 2072 } else { 2073 /* details: rombase sdk pp 4-15 */ 2074 if (pMga->PciInfo->biosBase != 0) { 2075 pMga->BiosAddress = pMga->PciInfo->biosBase & 0xffff0000; 2076 pMga->BiosFrom = X_PROBED; 2077 } else if (pMga->Primary) { 2078 pMga->BiosAddress = 0xc0000; 2079 pMga->BiosFrom = X_DEFAULT; 2080 } 2081 } 2082 if (pMga->BiosAddress) { 2083 xf86DrvMsg(pScrn->scrnIndex, pMga->BiosFrom, "BIOS at 0x%lX\n", 2084 (unsigned long)pMga->BiosAddress); 2085 } 2086#endif 2087 2088 2089 if (xf86RegisterResources(pMga->pEnt->index, NULL, ResExclusive)) { 2090 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2091 "xf86RegisterResources() found resource conflicts\n"); 2092 MGAFreeRec(pScrn); 2093 return FALSE; 2094 } 2095 2096 /* 2097 * Read the BIOS data struct 2098 */ 2099 2100#if defined(__alpha__) && !defined(XSERVER_LIBPCIACCESS) 2101 /* 2102 * Some old Digital-OEMed Matrox Millennium I cards have a VGA 2103 * disable switch. If the disable is on, we can't read the BIOS, 2104 * and pMga->BiosAddress = 0x0. The disable switch is needed to 2105 * allow multi-head operation with brain-dead console code... ;-} 2106 */ 2107 2108 if ((pMga->BiosAddress == 0) && !xf86IsPrimaryPci(pMga->PciInfo)) 2109 xf86DrvMsg(pScrn->scrnIndex, pMga->BiosFrom, 2110 "BIOS not found, skipping read\n"); 2111 else 2112#endif 2113 mga_read_and_process_bios( pScrn ); 2114 2115 2116 /* Since the BIOS can swap DACs during the initialisation of G550, we need to 2117 * store which DAC this instance of the driver is taking care of. This is done 2118 * by checking a flag stored in the ROM by the BIOS at a fixed address. */ 2119 2120 if (!pMga->SecondCrtc) 2121 pMga->SecondOutput = FALSE; 2122 else 2123 pMga->SecondOutput = TRUE; 2124 2125 if (pMga->Chipset == PCI_CHIP_MGAG550) { 2126 if (!pMga->SecondCrtc) { 2127 pMga->SecondOutput = (pMga->BiosOutputMode & 0x1) ? TRUE : FALSE; 2128 } else { 2129 pMga->SecondOutput = (pMga->BiosOutputMode & 0x1) ? FALSE : TRUE; 2130 } 2131 } 2132 2133 2134 /* HW bpp matches reported bpp */ 2135 pMga->HwBpp = pScrn->bitsPerPixel; 2136 2137 /* 2138 * Reset card if it isn't primary one 2139 */ 2140 if ( (!pMga->Primary && !pMga->FBDev) || xf86IsPc98() ) 2141 MGASoftReset(pScrn); 2142 2143 /* 2144 * If the user has specified the amount of memory in the XF86Config 2145 * file, we respect that setting. 2146 */ 2147 from = X_PROBED; 2148 if (pMga->device->videoRam != 0) { 2149 pScrn->videoRam = pMga->device->videoRam; 2150 from = X_CONFIG; 2151 } else if (pMga->FBDev) { 2152 pScrn->videoRam = fbdevHWGetVidmem(pScrn)/1024; 2153 } else { 2154 pScrn->videoRam = MGACountRam(pScrn); 2155 } 2156 2157 if (pScrn->videoRam == 0) { 2158 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2159 "Unable to detect video RAM.\n"); 2160 return FALSE; 2161 } 2162 2163 if (pMga->DualHeadEnabled) { 2164 /* This takes gives either half or 8 meg to the second head 2165 * whichever is less. */ 2166 if(pMga->SecondCrtc == FALSE) { 2167 Bool UseHalf = FALSE; 2168 int adjust; 2169 2170 xf86GetOptValBool(pMga->Options, OPTION_CRTC2HALF, &UseHalf); 2171 adjust = pScrn->videoRam / 2; 2172 2173 if (UseHalf == TRUE || 2174 xf86GetOptValInteger(pMga->Options, OPTION_CRTC2RAM, &adjust)) { 2175 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 2176 "Crtc2 will use %dK of VideoRam\n", 2177 adjust); 2178 } else { 2179 adjust = min(adjust, 8192); 2180 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2181 "Crtc2 will use %dK of VideoRam\n", 2182 adjust); 2183 } 2184 pMgaEnt->mastervideoRam = pScrn->videoRam - adjust; 2185 pScrn->videoRam = pMgaEnt->mastervideoRam; 2186 pMgaEnt->slavevideoRam = adjust; 2187 pMgaEnt->masterFbAddress = pMga->FbAddress; 2188 pMga->FbMapSize = 2189 pMgaEnt->masterFbMapSize = pScrn->videoRam * 1024; 2190 pMgaEnt->slaveFbAddress = pMga->FbAddress + 2191 pMgaEnt->masterFbMapSize; 2192 pMgaEnt->slaveFbMapSize = pMgaEnt->slavevideoRam * 1024; 2193 pMga->realSrcOrg = pMga->SrcOrg = 0; 2194 pMga->DstOrg = 0; 2195 } else { 2196 pMga->FbAddress = pMgaEnt->slaveFbAddress; 2197 pMga->FbMapSize = pMgaEnt->slaveFbMapSize; 2198 pScrn->videoRam = pMgaEnt->slavevideoRam; 2199 pMga->DstOrg = pMga->realSrcOrg = 2200 pMgaEnt->slaveFbAddress - pMgaEnt->masterFbAddress; 2201 pMga->SrcOrg = 0; /* This is not stored in hw format!! */ 2202 } 2203 pMgaEnt->refCount++; 2204 } else { 2205 /* Normal Handling of video ram etc */ 2206 pMga->FbMapSize = pScrn->videoRam * 1024; 2207 switch(pMga->Chipset) { 2208 case PCI_CHIP_MGAG550: 2209 case PCI_CHIP_MGAG400: 2210 case PCI_CHIP_MGAG200: 2211 case PCI_CHIP_MGAG200_PCI: 2212 case PCI_CHIP_MGAG200_SE_A_PCI: 2213 case PCI_CHIP_MGAG200_SE_B_PCI: 2214 pMga->SrcOrg = 0; 2215 pMga->DstOrg = 0; 2216 break; 2217 default: 2218 break; 2219 } 2220 } 2221 xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n", 2222 pScrn->videoRam); 2223 2224 /* Set the bpp shift value */ 2225 pMga->BppShifts[0] = 0; 2226 pMga->BppShifts[1] = 1; 2227 pMga->BppShifts[2] = 0; 2228 pMga->BppShifts[3] = 2; 2229 2230 /* 2231 * fill MGAdac struct 2232 * Warning: currently, it should be after RAM counting 2233 */ 2234 (*pMga->PreInit)(pScrn); 2235 2236#if !defined(__powerpc__) 2237 2238 /* Read and print the Monitor DDC info */ 2239 pScrn->monitor->DDC = MGAdoDDC(pScrn); 2240#endif /* !__powerpc__ */ 2241 2242 if (!pScrn->monitor->DDC && pMga->is_G200SE) { 2243 /* Jam in ranges big enough for 1024x768 */ 2244 if (!pScrn->monitor->nHsync) { 2245 pScrn->monitor->nHsync = 1; 2246 pScrn->monitor->hsync[0].lo = 31.5; 2247 pScrn->monitor->hsync[0].hi = 48.0; 2248 } 2249 if (!pScrn->monitor->nVrefresh) { 2250 pScrn->monitor->nVrefresh = 1; 2251 pScrn->monitor->vrefresh[0].lo = 56.0; 2252 pScrn->monitor->vrefresh[0].hi = 75.0; 2253 } 2254 } 2255 2256 2257 /* 2258 * If the driver can do gamma correction, it should call xf86SetGamma() 2259 * here. 2260 */ 2261 2262 { 2263 Gamma zeros = {0.0, 0.0, 0.0}; 2264 2265 if (!xf86SetGamma(pScrn, zeros)) { 2266 return FALSE; 2267 } 2268 } 2269 2270 2271 /* XXX Set HW cursor use */ 2272 2273 /* Set the min pixel clock */ 2274 pMga->MinClock = 17750; 2275 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n", 2276 pMga->MinClock / 1000); 2277 /* 2278 * If the user has specified ramdac speed in the XF86Config 2279 * file, we respect that setting. 2280 */ 2281 if (pMga->device->dacSpeeds[0]) { 2282 int speed = 0; 2283 2284 switch (pScrn->bitsPerPixel) { 2285 case 8: 2286 speed = pMga->device->dacSpeeds[DAC_BPP8]; 2287 break; 2288 case 16: 2289 speed = pMga->device->dacSpeeds[DAC_BPP16]; 2290 break; 2291 case 24: 2292 speed = pMga->device->dacSpeeds[DAC_BPP24]; 2293 break; 2294 case 32: 2295 speed = pMga->device->dacSpeeds[DAC_BPP32]; 2296 break; 2297 } 2298 if (speed == 0) 2299 pMga->MaxClock = pMga->device->dacSpeeds[0]; 2300 else 2301 pMga->MaxClock = speed; 2302 from = X_CONFIG; 2303 } else { 2304 pMga->MaxClock = pMga->Dac.maxPixelClock; 2305 from = pMga->Dac.ClockFrom; 2306 } 2307 if(pMga->SecondCrtc == TRUE) { 2308 /* Override on 2nd crtc */ 2309 if ((pMga->ChipRev >= 0x80) || (pMga->Chipset == PCI_CHIP_MGAG550)) { 2310 /* G450, G550 */ 2311 pMga->MaxClock = 234000; 2312 } else { 2313 pMga->MaxClock = 135000; 2314 } 2315 } 2316 xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n", 2317 pMga->MaxClock / 1000); 2318 /* 2319 * Setup the ClockRanges, which describe what clock ranges are available, 2320 * and what sort of modes they can be used for. 2321 */ 2322 clockRanges = xnfcalloc(sizeof(ClockRange), 1); 2323 clockRanges->next = NULL; 2324 clockRanges->minClock = pMga->MinClock; 2325 clockRanges->maxClock = pMga->MaxClock; 2326 clockRanges->clockIndex = -1; /* programmable */ 2327 clockRanges->interlaceAllowed = TRUE; 2328 clockRanges->doubleScanAllowed = TRUE; 2329#ifdef USEMGAHAL 2330 MGA_HAL(clockRanges->interlaceAllowed = FALSE); 2331 MGA_HAL(clockRanges->doubleScanAllowed = FALSE); 2332#endif 2333 if (pMga->SecondCrtc == TRUE) 2334 clockRanges->interlaceAllowed = FALSE; 2335 2336 clockRanges->ClockMulFactor = 1; 2337 clockRanges->ClockDivFactor = 1; 2338 2339 /* Only set MemClk if appropriate for the ramdac */ 2340 if (pMga->Dac.SetMemClk) { 2341 if (pMga->MemClk == 0) { 2342 pMga->MemClk = pMga->Dac.MemoryClock; 2343 from = pMga->Dac.MemClkFrom; 2344 } else 2345 from = X_CONFIG; 2346 xf86DrvMsg(pScrn->scrnIndex, from, "MCLK used is %.1f MHz\n", 2347 pMga->MemClk / 1000.0); 2348 } 2349 2350 /* 2351 * xf86ValidateModes will check that the mode HTotal and VTotal values 2352 * don't exceed the chipset's limit if pScrn->maxHValue and 2353 * pScrn->maxVValue are set. Since our MGAValidMode() already takes 2354 * care of this, we don't worry about setting them here. 2355 */ 2356 { 2357 int Pitches1[] = 2358 {640, 768, 800, 960, 1024, 1152, 1280, 1600, 1920, 2048, 0}; 2359 int Pitches2[] = 2360 {512, 640, 768, 800, 832, 960, 1024, 1152, 1280, 1600, 1664, 2361 1920, 2048, 0}; 2362 int *linePitches = NULL; 2363 int minPitch = 256; 2364 int maxPitch = 2048; 2365 2366 switch(pMga->Chipset) { 2367 case PCI_CHIP_MGA2064: 2368 if (!pMga->NoAccel) { 2369 linePitches = xalloc(sizeof(Pitches1)); 2370 memcpy(linePitches, Pitches1, sizeof(Pitches1)); 2371 minPitch = maxPitch = 0; 2372 } 2373 break; 2374 case PCI_CHIP_MGA2164: 2375 case PCI_CHIP_MGA2164_AGP: 2376 case PCI_CHIP_MGA1064: 2377 if (!pMga->NoAccel) { 2378 linePitches = xalloc(sizeof(Pitches2)); 2379 memcpy(linePitches, Pitches2, sizeof(Pitches2)); 2380 minPitch = maxPitch = 0; 2381 } 2382 break; 2383 case PCI_CHIP_MGAG100: 2384 case PCI_CHIP_MGAG100_PCI: 2385 maxPitch = 2048; 2386 break; 2387 case PCI_CHIP_MGAG200: 2388 case PCI_CHIP_MGAG200_PCI: 2389 case PCI_CHIP_MGAG200_SE_A_PCI: 2390 case PCI_CHIP_MGAG200_SE_B_PCI: 2391 case PCI_CHIP_MGAG400: 2392 case PCI_CHIP_MGAG550: 2393 maxPitch = 4096; 2394 break; 2395 } 2396 2397 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 2398 pScrn->display->modes, clockRanges, 2399 linePitches, minPitch, maxPitch, 2400 pMga->Roundings[(pScrn->bitsPerPixel >> 3) - 1] * 2401 pScrn->bitsPerPixel, 128, 2048, 2402 pScrn->display->virtualX, 2403 pScrn->display->virtualY, 2404 pMga->FbMapSize, 2405 LOOKUP_BEST_REFRESH); 2406 2407 if (linePitches) 2408 xfree(linePitches); 2409 } 2410 2411 2412 if (i < 1 && pMga->FBDev) { 2413 fbdevHWUseBuildinMode(pScrn); 2414 pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */ 2415 i = 1; 2416 } 2417 if (i == -1) { 2418 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Validate Modes Failed\n"); 2419 MGAFreeRec(pScrn); 2420 return FALSE; 2421 } 2422 2423 /* Prune the modes marked as invalid */ 2424 xf86PruneDriverModes(pScrn); 2425 2426 if (i == 0 || pScrn->modes == NULL) { 2427 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); 2428 MGAFreeRec(pScrn); 2429 return FALSE; 2430 } 2431#ifdef USEMGAHAL 2432 MGA_HAL( 2433 2434 if(pMga->SecondCrtc == FALSE) { 2435 2436 pMga->pBoard = xalloc(sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize()); 2437 pMga->pClientStruct = xalloc(sizeof(CLIENTDATA)); 2438 pMga->pClientStruct->pMga = (MGAPtr) pMga; 2439 2440 MGAMapMem(pScrn); 2441 /* 2442 * For some reason the MGAOPM_DMA_BLIT bit needs to be set 2443 * on G200 before opening the HALlib. I don't know why. 2444 * MATROX: hint, hint. 2445 */ 2446 /*if (pMga->Chipset == PCI_CHIP_MGAG200 || 2447 pMga->Chipset == PCI_CHIP_MGAG200_PCI) */{ 2448 CARD32 opmode; 2449 opmode = INREG(MGAREG_OPMODE); 2450 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT | opmode); 2451 } 2452 /* wrapping OpenLibrary to fix broken registers. MATROX: hint, hint. */ 2453 MiscCtlReg = inMGAdac(MGA1064_MISC_CTL); 2454 MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA)); 2455 outMGAdac(MGA1064_MISC_CTL,MiscCtlReg); 2456 MGAUnmapMem(pScrn); 2457 pMga->pMgaHwInfo = xalloc(sizeof(MGAHWINFO)); 2458 MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo); 2459 2460 /* copy the board handles */ 2461 if (pMga->DualHeadEnabled) { 2462 pMgaEnt->pClientStruct = pMga->pClientStruct; 2463 pMgaEnt->pBoard = pMga->pBoard; 2464 pMgaEnt->pMgaHwInfo = pMga->pMgaHwInfo; 2465 } 2466 2467 } else { /* Second CRTC && entity is shared */ 2468 pMga->pBoard = pMgaEnt->pBoard; 2469 pMga->pClientStruct = pMgaEnt->pClientStruct; 2470 pMga->pMgaHwInfo = pMgaEnt->pMgaHwInfo; 2471 2472 } 2473 2474 MGAFillModeInfoStruct(pScrn,NULL); 2475 /* Fields usually handled by MGAFillModeInfoStruct, but are unavailable 2476 * because no mode is given 2477 */ 2478 pMga->pMgaModeInfo->ulDispWidth = pScrn->virtualX; 2479 pMga->pMgaModeInfo->ulDispHeight = pScrn->virtualY; 2480 2481 2482 if (ISDIGITAL1(pMga)) 2483 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2484 "Digital screen detected on first head.\n"); 2485 if (ISTV1(pMga)) 2486 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2487 "TV detected on first head.\n"); 2488 if (ISDIGITAL2(pMga)) 2489 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2490 "Digital screen detected on second head.\n"); 2491 if (ISTV2(pMga)) 2492 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2493 "TV detected on second head.\n"); 2494 2495 2496 if((status = MGAValidateMode(pMga->pBoard,pMga->pMgaModeInfo)) != 0) { 2497 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2498 "MGAValidateMode from HALlib found the mode to be invalid.\n" 2499 "\tError: 0x%lx\n", status); 2500 return FALSE; 2501 } 2502 pScrn->displayWidth = pMga->pMgaModeInfo->ulFBPitch; 2503 ); /* MGA_HAL */ 2504#endif 2505 2506 /* If the Device section explicitly set HasSDRAM, don't bother checking. 2507 */ 2508 if (!pMga->HasSDRAM) { 2509 if ((pMga->softbooted || pMga->Primary) 2510 && pMga->chip_attribs->probe_for_sdram) { 2511 uint32_t option_reg; 2512 2513#ifdef XSERVER_LIBPCIACCESS 2514 pci_device_cfg_read_u32(pMga->PciInfo, & option_reg, 2515 PCI_OPTION_REG); 2516#else 2517 option_reg = pciReadLong(pMga->PciTag, PCI_OPTION_REG); 2518#endif 2519 pMga->HasSDRAM = ((option_reg & (1 << 14)) == 0); 2520 } 2521 else { 2522 pMga->HasSDRAM = pMga->chip_attribs->has_sdram; 2523 } 2524 2525 if (pMga->HasSDRAM) { 2526 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Has SDRAM\n"); 2527 } 2528 } 2529 2530 /* 2531 * Set the CRTC parameters for all of the modes based on the type 2532 * of mode, and the chipset's interlace requirements. 2533 * 2534 * Calling this is required if the mode->Crtc* values are used by the 2535 * driver and if the driver doesn't provide code to set them. They 2536 * are not pre-initialised at all. 2537 */ 2538#ifdef USEMGAHAL 2539 MGA_HAL(xf86SetCrtcForModes(pScrn, 0)); 2540#endif 2541 MGA_NOT_HAL(xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V)); 2542 2543 /* Set the current mode to the first in the list */ 2544 pScrn->currentMode = pScrn->modes; 2545 2546 /* Print the list of modes being used */ 2547 xf86PrintModes(pScrn); 2548 2549 /* Set display resolution */ 2550 xf86SetDpi(pScrn, 0, 0); 2551 2552 /* 2553 * Compute the byte offset into the linear frame buffer where the 2554 * frame buffer data should actually begin. According to DDK misc.c 2555 * line 1023, if more than 4MB is to be displayed, YDSTORG must be set 2556 * appropriately to align memory bank switching, and this requires a 2557 * corresponding offset on linear frame buffer access. 2558 * This is only needed for WRAM. 2559 */ 2560 2561 pMga->YDstOrg = 0; 2562 if (pMga->chip_attribs->fb_4mb_quirk && 2563 (pScrn->virtualX * pScrn->virtualY * bytesPerPixel > 4*1024*1024)) { 2564 int offset; 2565 int offset_modulo = (pScrn->bitsPerPixel == 24) ? 12 : 4; 2566 int ydstorg_modulo = 64; 2567 2568 2569 if (pMga->Interleave) { 2570 offset_modulo <<= 1; 2571 ydstorg_modulo <<= 1; 2572 } 2573 2574 offset = (4*1024*1024) % (pScrn->displayWidth * bytesPerPixel); 2575 pMga->YDstOrg = offset / bytesPerPixel; 2576 2577 /* 2578 * When this was unconditional, it caused a line of horizontal garbage 2579 * at the middle right of the screen at the 4Meg boundary in 32bpp 2580 * (and presumably any other modes that use more than 4M). But it's 2581 * essential for 24bpp (it may not matter either way for 8bpp & 16bpp, 2582 * I'm not sure; I didn't notice problems when I checked with and 2583 * without.) 2584 * DRM Doug Merritt 12/97, submitted to XFree86 6/98 (oops) 2585 */ 2586 if (bytesPerPixel < 4) { 2587 while ((offset % offset_modulo) != 0 || 2588 (pMga->YDstOrg % ydstorg_modulo) != 0) { 2589 offset++; 2590 pMga->YDstOrg = offset / bytesPerPixel; 2591 } 2592 } 2593 } 2594 2595 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "YDstOrg is set to %d\n", 2596 pMga->YDstOrg); 2597 if(pMga->DualHeadEnabled) { 2598 if(pMga->SecondCrtc == FALSE) { 2599 pMga->FbUsableSize = pMgaEnt->masterFbMapSize; 2600 /* Allocate HW cursor buffer at the end of video ram */ 2601 if( pMga->HWCursor && pMga->Dac.CursorOffscreenMemSize ) { 2602 if( pScrn->virtualY * pScrn->displayWidth * 2603 pScrn->bitsPerPixel / 8 <= 2604 pMga->FbUsableSize - pMga->Dac.CursorOffscreenMemSize ) { 2605 pMga->FbUsableSize -= pMga->Dac.CursorOffscreenMemSize; 2606 pMga->FbCursorOffset = 2607 pMgaEnt->masterFbMapSize - 2608 pMga->Dac.CursorOffscreenMemSize; 2609 } else { 2610 pMga->HWCursor = FALSE; 2611 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2612 "Too little offscreen memory for HW cursor; " 2613 "using SW cursor\n"); 2614 } 2615 } 2616 } else { /* Second CRTC */ 2617 pMga->FbUsableSize = pMgaEnt->slaveFbMapSize; 2618 pMga->HWCursor = FALSE; 2619 } 2620 } else { 2621 pMga->FbUsableSize = pMga->FbMapSize - pMga->YDstOrg * bytesPerPixel; 2622 /* Allocate HW cursor buffer at the end of video ram */ 2623 if( pMga->HWCursor && pMga->Dac.CursorOffscreenMemSize ) { 2624 if( pScrn->virtualY * pScrn->displayWidth * 2625 pScrn->bitsPerPixel / 8 <= 2626 pMga->FbUsableSize - pMga->Dac.CursorOffscreenMemSize ) { 2627 pMga->FbUsableSize -= pMga->Dac.CursorOffscreenMemSize; 2628 pMga->FbCursorOffset = 2629 pMga->FbMapSize - pMga->Dac.CursorOffscreenMemSize; 2630 } else { 2631 pMga->HWCursor = FALSE; 2632 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2633 "Too little offscreen memory for HW cursor; " 2634 "using SW cursor\n"); 2635 } 2636 } 2637 } 2638 /* 2639 * XXX This should be taken into account in some way in the mode valdation 2640 * section. 2641 */ 2642 2643 2644 /* Load the required framebuffer */ 2645 if (pMga->Overlay8Plus24) { 2646 if (!xf86LoadSubModule(pScrn, "xf8_32bpp")) { 2647 MGAFreeRec(pScrn); 2648 return FALSE; 2649 } 2650 xf86LoaderReqSymLists(xf8_32bppSymbols, NULL); 2651 } else { 2652 if (!xf86LoadSubModule(pScrn, "fb")) { 2653 MGAFreeRec(pScrn); 2654 return FALSE; 2655 } 2656 xf86LoaderReqSymLists(fbSymbols, NULL); 2657 } 2658 2659 2660 /* Load XAA if needed */ 2661 if (!pMga->NoAccel) { 2662#ifdef USE_EXA 2663 if (pMga->Exa) { 2664 if (!xf86LoadSubModule(pScrn, "exa")) { 2665 MGAFreeRec(pScrn); 2666 return FALSE; 2667 } else xf86LoaderReqSymLists(exaSymbols, NULL); 2668 } else { 2669#endif 2670#ifdef USE_XAA 2671 if (!xf86LoadSubModule(pScrn, "xaa")) { 2672 MGAFreeRec(pScrn); 2673 return FALSE; 2674 } else xf86LoaderReqSymLists(xaaSymbols, NULL); 2675#endif 2676#ifdef USE_EXA 2677 } 2678#endif 2679 } 2680 2681 /* Load ramdac if needed */ 2682 if (pMga->HWCursor) { 2683 if (!xf86LoadSubModule(pScrn, "ramdac")) { 2684 MGAFreeRec(pScrn); 2685 return FALSE; 2686 } 2687 xf86LoaderReqSymLists(ramdacSymbols, NULL); 2688 } 2689 2690 /* Load shadowfb if needed */ 2691 if (pMga->ShadowFB) { 2692 if (!xf86LoadSubModule(pScrn, "shadowfb")) { 2693 MGAFreeRec(pScrn); 2694 return FALSE; 2695 } 2696 xf86LoaderReqSymLists(shadowSymbols, NULL); 2697 } 2698 2699#ifdef XF86DRI 2700 /* Load the dri module if requested. */ 2701 if (xf86ReturnOptValBool(pMga->Options, OPTION_DRI, FALSE)) { 2702 if (xf86LoadSubModule(pScrn, "dri")) { 2703 xf86LoaderReqSymLists(driSymbols, drmSymbols, NULL); 2704 } 2705 } 2706#endif 2707 pMga->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel; 2708 pMga->CurrentLayout.depth = pScrn->depth; 2709 pMga->CurrentLayout.displayWidth = pScrn->displayWidth; 2710 pMga->CurrentLayout.weight.red = pScrn->weight.red; 2711 pMga->CurrentLayout.weight.green = pScrn->weight.green; 2712 pMga->CurrentLayout.weight.blue = pScrn->weight.blue; 2713 pMga->CurrentLayout.Overlay8Plus24 = pMga->Overlay8Plus24; 2714 pMga->CurrentLayout.mode = pScrn->currentMode; 2715 2716 2717 2718 if(pMga->MergedFB) { 2719 MGAPreInitMergedFB(pScrn,flags); 2720 }; 2721 2722 2723#ifdef USEMGAHAL 2724 MGA_HAL( 2725 /* Close the library after preinit */ 2726 /* This needs to only happen after this board has completed preinit 2727 * both times 2728 */ 2729 2730 if(pMga->DualHeadEnabled) { 2731 /* Entity is shared make sure refcount == 2 */ 2732 /* If ref count is 2 then reset it to 0 */ 2733 if(pMgaEnt->refCount == 2) { 2734 /* Both boards have done there initialization */ 2735 MGACloseLibrary(pMga->pBoard); 2736 2737 if (pMga->pBoard) 2738 xfree(pMga->pBoard); 2739 if (pMga->pClientStruct) 2740 xfree(pMga->pClientStruct); 2741 if (pMga->pMgaModeInfo) 2742 xfree(pMga->pMgaModeInfo); 2743 if (pMga->pMgaHwInfo) 2744 xfree(pMga->pMgaHwInfo); 2745 pMgaEnt->refCount = 0; 2746 } 2747 } else { 2748 MGACloseLibrary(pMga->pBoard); 2749 2750 if (pMga->pBoard) 2751 xfree(pMga->pBoard); 2752 if (pMga->pClientStruct) 2753 xfree(pMga->pClientStruct); 2754 if (pMga->pMgaModeInfo) 2755 xfree(pMga->pMgaModeInfo); 2756 if (pMga->pMgaHwInfo) 2757 xfree(pMga->pMgaHwInfo); 2758 } 2759 2760 ); /* MGA_HAL */ 2761#endif 2762 2763 xf86SetPrimInitDone(pScrn->entityList[0]); 2764 2765 return TRUE; 2766} 2767 2768 2769/* 2770 * Map the framebuffer and MMIO memory. 2771 */ 2772 2773static Bool 2774MGAMapMem(ScrnInfoPtr pScrn) 2775{ 2776 MGAPtr pMga = MGAPTR(pScrn); 2777#ifdef XSERVER_LIBPCIACCESS 2778 struct pci_device *const dev = pMga->PciInfo; 2779 struct pci_mem_region *region; 2780 void **memory[2]; 2781 int i, err; 2782#endif 2783 2784 2785 if (!pMga->FBDev) { 2786#ifdef XSERVER_LIBPCIACCESS 2787 memory[pMga->io_bar] = &pMga->IOBase; 2788 memory[pMga->framebuffer_bar] = &pMga->FbBase; 2789 2790 for (i = 0; i < 2; i++) { 2791 region = &dev->regions[i]; 2792 err = pci_device_map_range(dev, 2793 region->base_addr, region->size, 2794 PCI_DEV_MAP_FLAG_WRITABLE, 2795 memory[i]); 2796 2797 if (err) { 2798 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2799 "Unable to map BAR %i. %s (%d)\n", 2800 i, strerror(err), err); 2801 return FALSE; 2802 } 2803 } 2804#else 2805 /* 2806 * For Alpha, we need to map SPARSE memory, since we need 2807 * byte/short access. This is taken care of automatically by the 2808 * os-support layer. 2809 */ 2810 pMga->IOBase = xf86MapPciMem(pScrn->scrnIndex, 2811 VIDMEM_MMIO | VIDMEM_READSIDEEFFECT, 2812 pMga->PciTag, pMga->IOAddress, 0x4000); 2813 if (pMga->IOBase == NULL) 2814 return FALSE; 2815 2816 pMga->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 2817 pMga->PciTag, pMga->FbAddress, 2818 pMga->FbMapSize); 2819 if (pMga->FbBase == NULL) 2820 return FALSE; 2821#endif 2822 } 2823 else { 2824 pMga->FbBase = fbdevHWMapVidmem(pScrn); 2825 if (pMga->FbBase == NULL) { 2826 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2827 "Unable to map framebuffer.\n"); 2828 return FALSE; 2829 } 2830 2831 pMga->IOBase = fbdevHWMapMMIO(pScrn); 2832 if (pMga->IOBase == NULL) { 2833 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to map MMIO.\n"); 2834 return FALSE; 2835 } 2836 } 2837 2838 2839 pMga->FbStart = pMga->FbBase + pMga->YDstOrg * (pScrn->bitsPerPixel / 8); 2840 2841 pMga->ILOADBase = NULL; 2842 if (pMga->iload_bar != -1) { 2843#ifdef XSERVER_LIBPCIACCESS 2844 region = &dev->regions[pMga->iload_bar]; 2845 err = pci_device_map_range(dev, 2846 region->base_addr, region->size, 2847 PCI_DEV_MAP_FLAG_WRITABLE, 2848 (void *) &pMga->ILOADBase); 2849 if (err) { 2850 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2851 "Unable to map BAR 2 (ILOAD region). %s (%d)\n", 2852 strerror(err), err); 2853 return FALSE; 2854 } 2855#else 2856 pMga->ILOADBase = xf86MapPciMem(pScrn->scrnIndex, 2857 VIDMEM_MMIO | VIDMEM_MMIO_32BIT | 2858 VIDMEM_READSIDEEFFECT, 2859 pMga->PciTag, pMga->ILOADAddress, 2860 0x800000); 2861#endif 2862 } 2863 2864 2865 return TRUE; 2866} 2867 2868 2869/* 2870 * Unmap the framebuffer and MMIO memory. 2871 */ 2872 2873static Bool 2874MGAUnmapMem(ScrnInfoPtr pScrn) 2875{ 2876 MGAPtr pMga = MGAPTR(pScrn); 2877#ifdef XSERVER_LIBPCIACCESS 2878 struct pci_device * const dev = pMga->PciInfo; 2879#endif 2880 2881 2882 if (!pMga->FBDev) { 2883#ifdef XSERVER_LIBPCIACCESS 2884 pci_device_unmap_range(dev, pMga->IOBase, 2885 dev->regions[pMga->io_bar].size); 2886 pci_device_unmap_range(dev, pMga->FbBase, 2887 dev->regions[pMga->framebuffer_bar].size); 2888#else 2889 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->IOBase, 0x4000); 2890 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->FbBase, pMga->FbMapSize); 2891#endif 2892 } 2893 else { 2894 fbdevHWUnmapVidmem(pScrn); 2895 fbdevHWUnmapMMIO(pScrn); 2896 } 2897 2898 if ((pMga->iload_bar != -1) && (pMga->ILOADBase != NULL)) { 2899#ifdef XSERVER_LIBPCIACCESS 2900 pci_device_unmap_range(dev, pMga->ILOADBase, 2901 dev->regions[pMga->iload_bar].size); 2902#else 2903 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->ILOADBase, 0x800000); 2904#endif 2905 } 2906 2907 pMga->IOBase = NULL; 2908 pMga->FbBase = NULL; 2909 pMga->FbStart = NULL; 2910 pMga->ILOADBase = NULL; 2911 2912 return TRUE; 2913} 2914 2915 2916/* 2917 * This function saves the video state. 2918 */ 2919static void 2920MGASave(ScrnInfoPtr pScrn) 2921{ 2922 vgaHWPtr hwp = VGAHWPTR(pScrn); 2923 vgaRegPtr vgaReg = &hwp->SavedReg; 2924 MGAPtr pMga = MGAPTR(pScrn); 2925 MGARegPtr mgaReg = &pMga->SavedReg; 2926 2927 if(pMga->SecondCrtc == TRUE) return; 2928#ifdef USEMGAHAL 2929 MGA_HAL(if (pMga->pBoard != NULL) MGASaveVgaState(pMga->pBoard)); 2930#endif 2931 2932 /* I need to save the registers for the second head also */ 2933 /* Save the register for 0x80 to 0xa0 */ 2934 /* Could call it dac2Saved */ 2935 2936 /* Only save text mode fonts/text for the primary card */ 2937 (*pMga->Save)(pScrn, vgaReg, mgaReg, pMga->Primary); 2938} 2939 2940#ifdef USEMGAHAL 2941/* Convert DisplayModeRec parameters in MGAMODEINFO parameters. 2942* mode parameter optionnal. */ 2943void 2944MGAFillModeInfoStruct(ScrnInfoPtr pScrn, DisplayModePtr mode) 2945{ 2946 const char *s; 2947 MGAPtr pMga = MGAPTR(pScrn); 2948 2949 Bool digital1 = FALSE; 2950 Bool digital2 = FALSE; 2951 Bool tv1 = FALSE; 2952 Bool tv2 = FALSE; 2953 Bool swap_head 2954 = xf86ReturnOptValBool(pMga->Options, OPTION_SWAPPED_HEAD, FALSE); 2955 2956 if(pMga->MergedFB && mode && mode->Private && (mode->PrivSize == 0)) { 2957 mode = pMga->SecondCrtc ? 2958 ((MergedDisplayModePtr)mode->Private)->Monitor2 2959 : ((MergedDisplayModePtr)mode->Private)->Monitor1; 2960 } 2961 2962 2963 if (pMga->pMgaHwInfo) 2964 { 2965 digital1 = ISDIGITAL1(pMga); 2966 digital2 = ISDIGITAL2(pMga); 2967 tv1 = ISTV1(pMga); 2968 tv2 = ISTV2(pMga); 2969 } 2970 2971 /*FIXME: causes segfault elsewhere if not commented*/ 2972 /*if(!pMga->pMgaModeInfo)*/ pMga->pMgaModeInfo = xalloc(sizeof(MGAMODEINFO)); 2973 pMga->pMgaModeInfo->flOutput = 0; 2974 pMga->pMgaModeInfo->ulDeskWidth = pScrn->virtualX; 2975 pMga->pMgaModeInfo->ulDeskHeight = pScrn->virtualY; 2976 pMga->pMgaModeInfo->ulFBPitch = 0; 2977 pMga->pMgaModeInfo->ulBpp = pScrn->bitsPerPixel; 2978 pMga->pMgaModeInfo->ulZoom = 1; 2979 pMga->pMgaModeInfo->flSignalMode = 0x10; 2980 2981 /* Set TV standard */ 2982 if ((s = xf86GetOptValString(pMga->Options, OPTION_TVSTANDARD))) { 2983 if (!xf86NameCmp(s, "PAL")) { 2984 pMga->pMgaModeInfo->flSignalMode = 0x00; 2985 pMga->pMgaModeInfo->ulRefreshRate = 50; 2986 pMga->pMgaModeInfo->ulTVStandard = TV_PAL; 2987 } else { 2988 pMga->pMgaModeInfo->ulRefreshRate = 60; 2989 pMga->pMgaModeInfo->ulTVStandard = TV_NTSC; 2990 } 2991 } else { 2992 pMga->pMgaModeInfo->ulRefreshRate = 0; 2993 pMga->pMgaModeInfo->ulTVStandard = TV_NTSC; 2994 } 2995 2996 /* Set Cable Type */ 2997 if ((s = xf86GetOptValString(pMga->Options, OPTION_CABLETYPE))) { 2998 if (!xf86NameCmp(s, "SCART_RGB")) { 2999 pMga->pMgaModeInfo->ulCableType = TV_SCART_RGB; 3000 } else if (!xf86NameCmp(s, "SCART_COMPOSITE")) { 3001 pMga->pMgaModeInfo->ulCableType = TV_SCART_COMPOSITE; 3002 } else if (!xf86NameCmp(s, "SCART_TYPE2")) { 3003 pMga->pMgaModeInfo->ulCableType = TV_SCART_TYPE2; 3004 } else { 3005 pMga->pMgaModeInfo->ulCableType = TV_YC_COMPOSITE; 3006 } 3007 } else { 3008 pMga->pMgaModeInfo->ulCableType = TV_YC_COMPOSITE; 3009 } 3010 3011 if(mode) { 3012 pMga->pMgaModeInfo->ulHorizRate = 0; 3013 pMga->pMgaModeInfo->ulDispWidth = mode->HDisplay; 3014 pMga->pMgaModeInfo->ulDispHeight = mode->VDisplay; 3015 pMga->pMgaModeInfo->ulPixClock = mode->Clock; 3016 pMga->pMgaModeInfo->ulHFPorch = mode->HSyncStart - mode->HDisplay; 3017 pMga->pMgaModeInfo->ulHSync = mode->HSyncEnd - mode->HSyncStart; 3018 pMga->pMgaModeInfo->ulHBPorch = mode->HTotal - mode->HSyncEnd; 3019 pMga->pMgaModeInfo->ulVFPorch = mode->VSyncStart - mode->VDisplay; 3020 pMga->pMgaModeInfo->ulVSync = mode->VSyncEnd - mode->VSyncStart; 3021 pMga->pMgaModeInfo->ulVBPorch = mode->VTotal - mode->VSyncEnd; 3022 } 3023 /* Use DstOrg directly */ 3024 /* This is an offset in pixels not memory */ 3025 pMga->pMgaModeInfo->ulDstOrg = pMga->DstOrg / (pScrn->bitsPerPixel / 8); 3026 pMga->pMgaModeInfo->ulDisplayOrg = pMga->DstOrg / (pScrn->bitsPerPixel / 8); 3027 pMga->pMgaModeInfo->ulPanXGran = 0; 3028 pMga->pMgaModeInfo->ulPanYGran = 0; 3029 3030 if(pMga->SecondCrtc == TRUE) { 3031 pMga->pMgaModeInfo->flOutput = MGAMODEINFO_SECOND_CRTC | 3032 MGAMODEINFO_FORCE_PITCH | 3033 MGAMODEINFO_FORCE_DISPLAYORG; 3034 if (digital2) { 3035 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_DIGITAL2; 3036 } else if (tv2) { 3037 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_TV; 3038 } else { 3039 if (!swap_head) { 3040 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG2; 3041 } else { 3042 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG1; 3043 } 3044 } 3045 } else { 3046 pMga->pMgaModeInfo->flOutput = MGAMODEINFO_FORCE_PITCH; 3047 if (digital1) { 3048 if ((pMga->Chipset == PCI_CHIP_MGAG200) || 3049 (pMga->Chipset == PCI_CHIP_MGAG200_PCI)) { 3050 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_FLATPANEL1; 3051 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_DIGITAL2; 3052 } else { 3053 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_DIGITAL1; 3054 } 3055 } else if (tv1) { 3056 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_TV; 3057 } else { 3058 if (!swap_head) { 3059 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG1; 3060 } else { 3061 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG2; 3062 } 3063 } 3064 } 3065 pMga->pMgaModeInfo->ulFBPitch = pScrn->displayWidth; 3066} 3067#endif 3068 3069/* 3070 * Initialise a new mode. This is currently still using the old 3071 * "initialise struct, restore/write struct to HW" model. That could 3072 * be changed. 3073 */ 3074 3075static Bool 3076MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 3077{ 3078 vgaHWPtr hwp = VGAHWPTR(pScrn); 3079 vgaRegPtr vgaReg; 3080 MGAPtr pMga = MGAPTR(pScrn); 3081 MGARegPtr mgaReg; 3082 3083#ifdef USEMGAHAL 3084 ULONG status; 3085#endif 3086 vgaHWUnlock(hwp); 3087 3088/* if(pMga->MergedFB && mode && mode->Private && (mode->PrivSize == 0)) { 3089 mode = (DisplayModePtr)mode->Private; 3090 }*/ 3091 3092 /* Initialise the ModeReg values */ 3093 if (!vgaHWInit(pScrn, mode)) 3094 return FALSE; 3095 pScrn->vtSema = TRUE; 3096 3097 if (!(*pMga->ModeInit)(pScrn, mode)) 3098 return FALSE; 3099 3100 /* Program the registers */ 3101 if (pMga->is_G200SE) { 3102 MGAG200SEHWProtect(pScrn, TRUE); 3103 } else { 3104 vgaHWProtect(pScrn, TRUE); 3105 } 3106 vgaReg = &hwp->ModeReg; 3107 mgaReg = &pMga->ModeReg; 3108#ifdef USEMGAHAL 3109 MGA_HAL( 3110 MGAFillModeInfoStruct(pScrn,mode); 3111 3112 /* Validate the parameters */ 3113 if ((status = MGAValidateMode(pMga->pBoard, pMga->pMgaModeInfo)) != 0) { 3114 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3115 "MGAValidateMode from HALlib found the mode to be invalid.\n" 3116 "\tError: %lx\n", status); 3117 return FALSE; 3118 } 3119 3120 /* 3121 * Find mode for second head. 3122 */ 3123 if(pMga->MergedFB) { 3124 3125 MGAFillModeInfoStruct(pMga->pScrn2,mode); 3126 /* Validates the Video parameters */ 3127 if ((status = MGAValidateVideoParameters(pMga->pBoard, MGAPTR(pMga->pScrn2)->pMgaModeInfo)) 3128 != 0) { 3129 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3130 "MGAValidateVideoParameters from HALlib found the mode to be invalid.\n\tError: %lx\n", status); 3131 return FALSE; 3132 } 3133 } 3134 ); /*MGA_HAL */ 3135 3136#endif 3137 3138#ifdef USEMGAHAL 3139MGA_HAL( 3140 3141 /*************************** ESC *****************************/ 3142 TmpMgaModeInfo[0] = *pMga->pMgaModeInfo; 3143 3144 if(pMga->SecondCrtc == TRUE) 3145 pMgaModeInfo[1] = pMga->pMgaModeInfo; 3146 else 3147 pMgaModeInfo[0] = pMga->pMgaModeInfo; 3148 3149 TmpMgaModeInfo[0].ulDispWidth = 0; 3150 3151 if(!pMga->MergedFB) /* FIXME: Must deal with this once PowerDesk & MergedFB 3152 compatibility will exist */ 3153 MGAFillDisplayModeStruct(mode, pMga->pMgaModeInfo); 3154 /*************************************************************/ 3155 3156); /* MGA_HAL */ 3157#endif 3158 3159#ifdef XF86DRI 3160 if (pMga->directRenderingEnabled) { 3161 DRILock(screenInfo.screens[pScrn->scrnIndex], 0); 3162 } 3163#endif 3164 3165#ifdef USEMGAHAL 3166 MGA_HAL( 3167 /* Initialize the board */ 3168 if(MGASetMode(pMga->pBoard,pMga->pMgaModeInfo) != 0) { 3169 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3170 "MGASetMode returned an error." 3171 " Make sure to validate the mode before.\n"); 3172 return FALSE; 3173 } 3174 if(pMga->MergedFB 3175 && MGASetMode(pMga->pBoard,MGAPTR(pMga->pScrn2)->pMgaModeInfo) != 0) { 3176 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3177 "MGASetMode returned an error." 3178 " Make sure to validate the mode before.\n"); 3179 } 3180 3181 ); /* MGA_HAL */ 3182 3183 /* getting around bugs in the HAL lib. MATROX: hint, hint. */ 3184 MGA_HAL( 3185 if (pMga->chip_attribs->hwcursor_1064) { 3186 if(pMga->SecondCrtc == FALSE && pMga->HWCursor == TRUE) { 3187 outMGAdac(MGA1064_CURSOR_BASE_ADR_LOW, 3188 pMga->FbCursorOffset >> 10); 3189 outMGAdac(MGA1064_CURSOR_BASE_ADR_HI, 3190 pMga->FbCursorOffset >> 18); 3191 outMGAdac(MGA1064_CURSOR_CTL, 0x00); 3192 } 3193 if (pMga->Overlay8Plus24 == TRUE) { 3194 outMGAdac(MGA1064_MUL_CTL, MGA1064_MUL_CTL_32bits); 3195 outMGAdac(MGA1064_COL_KEY_MSK_LSB,0xFF); 3196 outMGAdac(MGA1064_COL_KEY_LSB,pMga->colorKey); 3197 outMGAdac(MGA1064_COL_KEY_MSK_MSB,0xFF); 3198 outMGAdac(MGA1064_COL_KEY_MSB,0xFF); 3199 } 3200 } 3201 ); /* MGA_HAL */ 3202#endif 3203 3204 MGA_NOT_HAL((*pMga->Restore)(pScrn, vgaReg, mgaReg, FALSE)); 3205 3206 MGAStormSync(pScrn); 3207 MGAStormEngineInit(pScrn); 3208 3209 if (pMga->is_G200SE) { 3210 MGAG200SEHWProtect(pScrn,FALSE); 3211 } else { 3212 vgaHWProtect(pScrn, FALSE); 3213 } 3214 3215 if (xf86IsPc98()) { 3216 if (pMga->Chipset == PCI_CHIP_MGA2064) 3217 outb(0xfac, 0x01); 3218 else 3219 outb(0xfac, 0x02); 3220 } 3221 3222 MGA_NOT_HAL( 3223 if (pMga->is_G200SE) { 3224 OUTREG8(0x1FDE, 0x06); 3225 OUTREG8(0x1FDF, 0x14); 3226 } 3227 ); 3228 3229 pMga->CurrentLayout.mode = mode; 3230 3231 if(pMga->MergedFB && mode->Private && (mode->PrivSize == 0)) { 3232 pMga->M1currentMode = (DisplayModePtr)mode->Private; 3233 } 3234 3235#ifdef XF86DRI 3236 if (pMga->directRenderingEnabled) 3237 DRIUnlock(screenInfo.screens[pScrn->scrnIndex]); 3238#endif 3239#ifdef DEBUG 3240 MGAG450PrintPLL(pScrn); 3241#endif 3242 return TRUE; 3243} 3244 3245static 3246void MGARestoreSecondCrtc(ScrnInfoPtr pScrn) 3247{ 3248 MGAPtr pMga = MGAPTR(pScrn); 3249 3250 if (MGAISGx50(pMga)) { 3251 /* Force to return in clone mode */ 3252 if (pMga->SecondOutput 3253 && (xf86IsEntityShared(pScrn->entityList[0]) || pMga->SecondCrtc) 3254 && !pMga->MergedFB) { 3255 /* Do this branch if 3256 * SecondOutput 3257 * and not Unshared Primary 3258 * and not Merged Mode (usualy means Unshared Primary) 3259 */ 3260 CARD8 ucXDispCtrl = inMGAdac(MGA1064_DISP_CTL); 3261 3262 ucXDispCtrl &= ~MGA1064_DISP_CTL_DAC2OUTSEL_MASK; 3263 ucXDispCtrl |= MGA1064_DISP_CTL_DAC2OUTSEL_CRTC1; 3264 3265 outMGAdac(MGA1064_DISP_CTL, ucXDispCtrl); 3266 3267 } else { 3268 CARD8 ucXDispCtrl = inMGAdac(MGA1064_DISP_CTL); 3269 CARD32 ulC2CTL = INREG(MGAREG_C2CTL); 3270 3271 ucXDispCtrl &= ~MGA1064_DISP_CTL_DAC2OUTSEL_MASK; 3272 ucXDispCtrl |= MGA1064_DISP_CTL_DAC1OUTSEL_EN; 3273 ucXDispCtrl |= MGA1064_DISP_CTL_DAC2OUTSEL_CRTC1; 3274 3275 /* crtcdacsel -> crtc1 */ 3276 ulC2CTL &= ~MGAREG_C2CTL_CRTCDACSEL_CRTC2; 3277 ulC2CTL |= MGAREG_C2CTL_CRTCDACSEL_CRTC1; 3278 3279 outMGAdac(MGA1064_DISP_CTL, ucXDispCtrl); 3280 OUTREG(MGAREG_C2CTL, ulC2CTL); 3281 } 3282 3283 } else { 3284 /* Force to close second crtc */ 3285 CARD32 ulC2CTL = INREG(MGAREG_C2CTL); 3286 3287 ulC2CTL &= ~MGAREG_C2CTL_C2_EN; 3288 3289 OUTREG(MGAREG_C2CTL, ulC2CTL); 3290 } 3291} 3292 3293/* 3294 * Restore the initial (text) mode. 3295 */ 3296static void 3297MGARestore(ScrnInfoPtr pScrn) 3298{ 3299 vgaHWPtr hwp = VGAHWPTR(pScrn); 3300 vgaRegPtr vgaReg = &hwp->SavedReg; 3301 MGAPtr pMga = MGAPTR(pScrn); 3302 MGARegPtr mgaReg = &pMga->SavedReg; 3303 3304 if (pScrn->pScreen != NULL) 3305 MGAStormSync(pScrn); 3306 3307 /* 3308 * Restore the second crtc if: 3309 * first and only driver entity 3310 * second entity 3311 * Merged Framebuffer mode (first and only driver entity) 3312 */ 3313 if((!xf86IsEntityShared(pScrn->entityList[0]) && !pMga->SecondCrtc) 3314 || pMga->SecondCrtc || pMga->MergedFB) { 3315 /* if(pMga->MergedFB) { 3316 if(pMga->pScrn2) 3317 MGARestoreSecondCrtc(pMga->pScrn2); 3318 } else*/ 3319 MGARestoreSecondCrtc(pScrn); 3320 /* if we are second instance of driver, we've done our job, exit */ 3321 if(pMga->SecondCrtc) return; 3322 } 3323 3324 /* Only restore text mode fonts/text for the primary card */ 3325 if (pMga->is_G200SE) { 3326 MGAG200SEHWProtect(pScrn,TRUE); 3327 } else { 3328 vgaHWProtect(pScrn, TRUE); 3329 } 3330 if (pMga->Primary) { 3331#ifdef USEMGAHAL 3332 MGA_HAL( 3333 if(pMga->pBoard != NULL) { 3334 MGASetVgaMode(pMga->pBoard); 3335 MGARestoreVgaState(pMga->pBoard); 3336 } 3337 ); /* MGA_HAL */ 3338#endif 3339 (*pMga->Restore)(pScrn, vgaReg, mgaReg, TRUE); 3340 } else { 3341 vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); 3342 } 3343 3344 if (pMga->is_G200SE) { 3345 MGAG200SEHWProtect(pScrn,FALSE); 3346 } else { 3347 vgaHWProtect(pScrn,FALSE); 3348 } 3349} 3350 3351 3352/* Workaround for a G400 CRTC2 display problem */ 3353static void 3354MGACrtc2FillStrip(ScrnInfoPtr pScrn) 3355{ 3356 MGAPtr pMga = MGAPTR(pScrn); 3357 3358 if (pMga->NoAccel) { 3359 /* Clears the whole screen, but ... */ 3360 bzero(pMga->FbStart, 3361 (pScrn->bitsPerPixel >> 3) * pScrn->displayWidth * pScrn->virtualY); 3362 } else { 3363 xf86SetLastScrnFlag(pScrn->entityList[0], pScrn->scrnIndex); 3364 pMga->RestoreAccelState(pScrn); 3365 pMga->SetupForSolidFill(pScrn, 0, GXcopy, 0xFFFFFFFF); 3366 pMga->SubsequentSolidFillRect(pScrn, pScrn->virtualX, 0, 3367 pScrn->displayWidth - pScrn->virtualX, 3368 pScrn->virtualY); 3369 MGAStormSync(pScrn); 3370 } 3371} 3372 3373 3374/* Mandatory */ 3375 3376/* This gets called at the start of each server generation */ 3377 3378static Bool 3379MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 3380{ 3381 ScrnInfoPtr pScrn; 3382 vgaHWPtr hwp; 3383 MGAPtr pMga; 3384 MGARamdacPtr MGAdac; 3385 int ret; 3386 VisualPtr visual; 3387 unsigned char *FBStart; 3388 int width, height, displayWidth; 3389 MGAEntPtr pMgaEnt = NULL; 3390 int f; 3391 CARD32 VRTemp, FBTemp; 3392#ifdef XF86DRI 3393 MessageType driFrom = X_DEFAULT; 3394#endif 3395 DPMSSetProcPtr mga_dpms_set_proc = NULL; 3396 3397 /* 3398 * First get the ScrnInfoRec 3399 */ 3400 pScrn = xf86Screens[pScreen->myNum]; 3401 3402 hwp = VGAHWPTR(pScrn); 3403 pMga = MGAPTR(pScrn); 3404 MGAdac = &pMga->Dac; 3405 3406 if (pMga->is_G200SE) { 3407 VRTemp = pScrn->videoRam; 3408 FBTemp = pMga->FbMapSize; 3409 pScrn->videoRam = 4096; 3410 pMga->FbMapSize = pScrn->videoRam * 1024; 3411 } 3412 3413 3414 /* Map the MGA memory and MMIO areas */ 3415 if (!MGAMapMem(pScrn)) 3416 return FALSE; 3417 3418 3419 /* Select functions that vary based on the CRTC configureation of the 3420 * screen. 3421 */ 3422 if (!pMga->MergedFB) { 3423 if (pMga->SecondCrtc) { 3424 mga_dpms_set_proc = MGADisplayPowerManagementSetCrtc2; 3425 pScreen->SaveScreen = MGASaveScreenCrtc2; 3426 } 3427 else { 3428 mga_dpms_set_proc = MGADisplayPowerManagementSet; 3429 pScreen->SaveScreen = MGASaveScreen; 3430 } 3431 } 3432 else { 3433 pScreen->SaveScreen = MGASaveScreenMerged; 3434 mga_dpms_set_proc = MGADisplayPowerManagementSetMerged; 3435 } 3436 3437 3438 if ((pMga->Chipset == PCI_CHIP_MGAG100) 3439 || (pMga->Chipset == PCI_CHIP_MGAG100_PCI)) 3440 MGAG100BlackMagic(pScrn); 3441 3442 if (pMga->DualHeadEnabled) { 3443 DevUnion *pPriv; 3444 pPriv = xf86GetEntityPrivate(pScrn->entityList[0], MGAEntityIndex); 3445 pMgaEnt = pPriv->ptr; 3446 pMgaEnt->refCount++; 3447#ifdef USEMGAHAL 3448 MGA_HAL( 3449 if(pMgaEnt->refCount == 1) { 3450 CARD8 MiscCtlReg; 3451 pMga->pBoard = xalloc(sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize()); 3452 pMga->pClientStruct = xalloc(sizeof(CLIENTDATA)); 3453 pMga->pClientStruct->pMga = (MGAPtr) pMga; 3454 3455 /* wrapping OpenLibrary to fix broken registers. MATROX: hint,hint.*/ 3456 MiscCtlReg = inMGAdac(MGA1064_MISC_CTL); 3457 MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA)); 3458 outMGAdac(MGA1064_MISC_CTL,MiscCtlReg); 3459 pMga->pMgaHwInfo = xalloc(sizeof(MGAHWINFO)); 3460 MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo); 3461 3462 /* Detecting for type of display */ 3463 if (pMga->pMgaHwInfo->ulCapsSecondOutput & MGAHWINFOCAPS_OUTPUT_TV) { 3464 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "TV detected\n"); 3465 } 3466 if (pMga->pMgaHwInfo->ulCapsFirstOutput & 3467 MGAHWINFOCAPS_OUTPUT_DIGITAL) { 3468 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3469 "Digital Screen detected\n"); 3470 } 3471 if (pMga->pMgaHwInfo->ulCapsSecondOutput & 3472 MGAHWINFOCAPS_OUTPUT_DIGITAL) { 3473 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3474 "Digital Screen detected\n"); 3475 } 3476 3477 /* Now copy these to the entitystructure */ 3478 pMgaEnt->pClientStruct = pMga->pClientStruct; 3479 pMgaEnt->pBoard = pMga->pBoard; 3480 pMgaEnt->pMgaHwInfo = pMga->pMgaHwInfo; 3481 } else { /* Ref count is 2 */ 3482 pMga->pClientStruct = pMgaEnt->pClientStruct; 3483 pMga->pBoard = pMgaEnt->pBoard; 3484 pMga->pMgaHwInfo = pMgaEnt->pMgaHwInfo; 3485 } 3486 ); /* MGA_HAL */ 3487#endif 3488 } else { 3489#ifdef USEMGAHAL 3490 CARD8 MiscCtlReg; 3491 3492 MGA_HAL( 3493 pMga->pBoard = xalloc(sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize()); 3494 pMga->pClientStruct = xalloc(sizeof(CLIENTDATA)); 3495 pMga->pClientStruct->pMga = (MGAPtr) pMga; 3496 3497 MiscCtlReg = inMGAdac(MGA1064_MISC_CTL); 3498 /* wrapping OpenLibrary to fix broken registers. MATROX: hint,hint.*/ 3499 MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA)); 3500 outMGAdac(MGA1064_MISC_CTL,MiscCtlReg); 3501 pMga->pMgaHwInfo = xalloc(sizeof(MGAHWINFO)); 3502 MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo); 3503 ); /* MGA_HAL */ 3504#endif 3505 } 3506 if (pMga->is_G200SE) { 3507 pScrn->videoRam = VRTemp; 3508 pMga->FbMapSize = FBTemp; 3509 } 3510#ifdef USEMGAHAL 3511 MGA_HAL( 3512 /* There is a problem in the HALlib: set soft reset bit */ 3513 /* MATROX: hint, hint. */ 3514 if (!pMga->Primary && !pMga->FBDev && 3515 (SUBSYS_ID(pMga->PciInfo) == PCI_CARD_MILL_G200_SG)) { 3516 OUTREG(MGAREG_Reset, 1); 3517 usleep(200); 3518 OUTREG(MGAREG_Reset, 0); 3519 } 3520 ); /* MGA_HAL */ 3521#endif 3522 3523 /* Initialise the MMIO vgahw functions */ 3524 vgaHWSetMmioFuncs(hwp, pMga->IOBase, PORT_OFFSET); 3525 vgaHWGetIOBase(hwp); 3526 3527 /* Map the VGA memory when the primary video */ 3528 if (!pMga->FBDev) { 3529 if (pMga->Primary) { 3530 hwp->MapSize = 0x10000; 3531 if (!vgaHWMapMem(pScrn)) 3532 return FALSE; 3533 } 3534 3535 /* Save the current state */ 3536 MGASave(pScrn); 3537 /* Initialise the first mode */ 3538 if (!MGAModeInit(pScrn, pScrn->currentMode)) 3539 return FALSE; 3540 } 3541 else { 3542 fbdevHWSave(pScrn); 3543 /* Disable VGA core, and leave memory access on */ 3544#ifdef XSERVER_LIBPCIACCESS 3545 pci_device_cfg_write_bits(pMga->PciInfo, 0x00000100, 0x00000000, 3546 PCI_OPTION_REG); 3547#else 3548 pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, 0x100, 0x000); 3549#endif 3550 if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) 3551 return FALSE; 3552 3553 if (!pMga->SecondCrtc && pMga->HWCursor 3554 && pMga->chip_attribs->hwcursor_1064) { 3555 outMGAdac(MGA1064_CURSOR_BASE_ADR_LOW, pMga->FbCursorOffset >> 10); 3556 outMGAdac(MGA1064_CURSOR_BASE_ADR_HI, pMga->FbCursorOffset >> 18); 3557 } 3558 3559 MGAStormEngineInit(pScrn); 3560 } 3561 3562 /* Darken the screen for aesthetic reasons and set the viewport 3563 */ 3564 (*pScreen->SaveScreen)(pScreen, SCREEN_SAVER_ON); 3565 pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 3566 3567 3568 /* 3569 * The next step is to setup the screen's visuals, and initialise the 3570 * framebuffer code. In cases where the framebuffer's default 3571 * choices for things like visual layouts and bits per RGB are OK, 3572 * this may be as simple as calling the framebuffer's ScreenInit() 3573 * function. If not, the visuals will need to be setup before calling 3574 * a fb ScreenInit() function and fixed up after. 3575 * 3576 * For most PC hardware at depths >= 8, the defaults that cfb uses 3577 * are not appropriate. In this driver, we fixup the visuals after. 3578 */ 3579 3580 /* 3581 * Reset the visual list. 3582 */ 3583 miClearVisualTypes(); 3584 3585 /* Setup the visuals we support. */ 3586 3587 /* All MGA support DirectColor and can do overlays in 32bpp */ 3588 if(pMga->Overlay8Plus24 && (pScrn->bitsPerPixel == 32)) { 3589 if (!miSetVisualTypes(8, PseudoColorMask | GrayScaleMask, 3590 pScrn->rgbBits, PseudoColor)) 3591 return FALSE; 3592 if (!miSetVisualTypes(24, TrueColorMask, pScrn->rgbBits, TrueColor)) 3593 return FALSE; 3594 } else if (pMga->SecondCrtc) { 3595 /* No DirectColor on the second head */ 3596 if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits, 3597 TrueColor)) 3598 return FALSE; 3599 if (!miSetPixmapDepths ()) 3600 return FALSE; 3601 } else { 3602 if (!xf86SetDefaultVisual(pScrn, -1)) 3603 return FALSE; 3604 3605 if (!miSetVisualTypes(pScrn->depth, 3606 miGetDefaultVisualMask(pScrn->depth), 3607 pScrn->rgbBits, pScrn->defaultVisual)) 3608 return FALSE; 3609 if (!miSetPixmapDepths ()) 3610 return FALSE; 3611 } 3612 3613 /* 3614 * Call the framebuffer layer's ScreenInit function, and fill in other 3615 * pScreen fields. 3616 */ 3617 3618 width = pScrn->virtualX; 3619 height = pScrn->virtualY; 3620 displayWidth = pScrn->displayWidth; 3621 3622 3623 if(pMga->Rotate) { 3624 height = pScrn->virtualX; 3625 width = pScrn->virtualY; 3626 } 3627 3628 if(pMga->ShadowFB) { 3629 pMga->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); 3630 pMga->ShadowPtr = xalloc(pMga->ShadowPitch * height); 3631 displayWidth = pMga->ShadowPitch / (pScrn->bitsPerPixel >> 3); 3632 FBStart = pMga->ShadowPtr; 3633 } else { 3634 pMga->ShadowPtr = NULL; 3635 FBStart = pMga->FbStart; 3636 } 3637 3638#ifdef XF86DRI 3639 /* 3640 * Setup DRI after visuals have been established, but before cfbScreenInit 3641 * is called. cfbScreenInit will eventually call into the drivers 3642 * InitGLXVisuals call back. 3643 * The DRI does not work when textured video is enabled at this time. 3644 */ 3645 if (pMga->is_G200SE) { 3646 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3647 "Not supported by hardware, not initializing the DRI\n"); 3648 pMga->directRenderingEnabled = FALSE; 3649 driFrom = X_PROBED; 3650 } else if (!xf86ReturnOptValBool(pMga->Options, OPTION_DRI, TRUE)) { 3651 driFrom = X_CONFIG; 3652 } else if ( pMga->NoAccel ) { 3653 xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 3654 "Acceleration disabled, not initializing the DRI\n" ); 3655 pMga->directRenderingEnabled = FALSE; 3656 driFrom = X_CONFIG; 3657 } 3658 else if ( pMga->TexturedVideo == TRUE ) { 3659 xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 3660 "Textured video enabled, not initializing the DRI\n" ); 3661 pMga->directRenderingEnabled = FALSE; 3662 driFrom = X_CONFIG; 3663 } 3664 else if (pMga->SecondCrtc == TRUE) { 3665 xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 3666 "Not initializing the DRI on the second head\n" ); 3667 pMga->directRenderingEnabled = FALSE; 3668 } 3669 else if ((pMga->FbMapSize / 3670 (width * (pScrn->bitsPerPixel >> 3))) <= height * 3) { 3671 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3672 "Static buffer allocation failed, not initializing the DRI\n"); 3673 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3674 "Need at least %d kB video memory at this resolution, bit depth\n", 3675 (3 * displayWidth * height * (pScrn->bitsPerPixel >> 3)) / 1024 ); 3676 pMga->directRenderingEnabled = FALSE; 3677 driFrom = X_PROBED; 3678 } 3679 else { 3680 pMga->directRenderingEnabled = MGADRIScreenInit(pScreen); 3681 } 3682#endif 3683 3684 3685 if (pMga->Overlay8Plus24) { 3686 ret = cfb8_32ScreenInit(pScreen, FBStart, 3687 width, height, 3688 pScrn->xDpi, pScrn->yDpi, 3689 displayWidth); 3690 } else { 3691 ret = fbScreenInit(pScreen, FBStart, width, height, 3692 pScrn->xDpi, pScrn->yDpi, 3693 displayWidth, pScrn->bitsPerPixel); 3694 } 3695 3696 if (!ret) 3697 return FALSE; 3698 3699 3700 if (pScrn->bitsPerPixel > 8) { 3701 /* Fixup RGB ordering */ 3702 visual = pScreen->visuals + pScreen->numVisuals; 3703 while (--visual >= pScreen->visuals) { 3704 if ((visual->class | DynamicClass) == DirectColor) { 3705 visual->offsetRed = pScrn->offset.red; 3706 visual->offsetGreen = pScrn->offset.green; 3707 visual->offsetBlue = pScrn->offset.blue; 3708 visual->redMask = pScrn->mask.red; 3709 visual->greenMask = pScrn->mask.green; 3710 visual->blueMask = pScrn->mask.blue; 3711 } 3712 } 3713 } 3714 3715 /* must be after RGB ordering fixed */ 3716 if (!pMga->Overlay8Plus24) 3717 fbPictureInit (pScreen, 0, 0); 3718 3719 xf86SetBlackWhitePixels(pScreen); 3720 3721 pMga->BlockHandler = pScreen->BlockHandler; 3722 pScreen->BlockHandler = MGABlockHandler; 3723 3724 if(!pMga->ShadowFB) /* hardware cursor needs to wrap this layer */ 3725 MGADGAInit(pScreen); 3726 3727 if (!pMga->NoAccel) { 3728#ifdef USE_EXA 3729 if (pMga->Exa) 3730 mgaExaInit(pScreen); 3731 else 3732#endif 3733#ifdef USE_XAA 3734 MGAStormAccelInit(pScreen); 3735#endif 3736 } 3737 3738 miInitializeBackingStore(pScreen); 3739 xf86SetBackingStore(pScreen); 3740 xf86SetSilkenMouse(pScreen); 3741 3742 /* Initialize software cursor. 3743 Must precede creation of the default colormap */ 3744 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 3745 3746 /* Initialize HW cursor layer. 3747 Must follow software cursor initialization*/ 3748 if (pMga->HWCursor) { 3749 if(!MGAHWCursorInit(pScreen)) 3750 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3751 "Hardware cursor initialization failed\n"); 3752 } 3753 if(pMga->MergedFB) { 3754 /* Rotate and MergedFB are mutiualy exclusive, so we can use this 3755 * variable. 3756 */ 3757 if (!pMga->PointerMoved) 3758 pMga->PointerMoved = pScrn->PointerMoved; 3759 pScrn->PointerMoved = MGAMergePointerMoved; 3760 3761 } 3762 3763 /* Initialise default colourmap */ 3764 if (!miCreateDefColormap(pScreen)) 3765 return FALSE; 3766 3767 /* Initialize colormap layer. 3768 Must follow initialization of the default colormap */ 3769 if (!pMga->SecondCrtc) 3770 f = CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH; 3771 else 3772 f = CMAP_RELOAD_ON_MODE_SWITCH; 3773 if(!xf86HandleColormaps(pScreen, 256, 8, 3774 pMga->FBDev ? fbdevHWLoadPaletteWeak() : MGAdac->LoadPalette, 3775 NULL, f)) 3776 return FALSE; 3777 3778 if(pMga->Overlay8Plus24) { /* Must come after colormap initialization */ 3779 if(!xf86Overlay8Plus32Init(pScreen)) 3780 return FALSE; 3781 } 3782 3783 if(pMga->ShadowFB) { 3784 RefreshAreaFuncPtr refreshArea = MGARefreshArea; 3785 3786 if(pMga->Rotate) { 3787 if (!pMga->PointerMoved) { 3788 pMga->PointerMoved = pScrn->PointerMoved; 3789 pScrn->PointerMoved = MGAPointerMoved; 3790 } 3791 3792 switch(pScrn->bitsPerPixel) { 3793 case 8: refreshArea = MGARefreshArea8; break; 3794 case 16: refreshArea = MGARefreshArea16; break; 3795 case 24: refreshArea = MGARefreshArea24; break; 3796 case 32: refreshArea = MGARefreshArea32; break; 3797 } 3798 } 3799 3800 ShadowFBInit(pScreen, refreshArea); 3801 } 3802 3803 xf86DPMSInit(pScreen, mga_dpms_set_proc, 0); 3804 3805 pScrn->memPhysBase = pMga->FbAddress; 3806 pScrn->fbOffset = pMga->YDstOrg * (pScrn->bitsPerPixel / 8); 3807 3808 MGAInitVideo(pScreen); 3809 3810#ifdef XF86DRI 3811 if (pMga->directRenderingEnabled) { 3812 /* Now that mi, cfb, drm and others have done their thing, 3813 * complete the DRI setup. 3814 */ 3815 pMga->directRenderingEnabled = MGADRIFinishScreenInit(pScreen); 3816 } 3817 if (pMga->directRenderingEnabled) { 3818 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); 3819 } else { 3820 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Direct rendering disabled\n"); 3821 } 3822 if (pMga->DualHeadEnabled && pMga->SecondCrtc == FALSE) 3823 pMgaEnt->directRenderingEnabled = pMga->directRenderingEnabled; 3824 pMga->haveQuiescense = 1; 3825#endif 3826 3827 /* Wrap the current CloseScreen function */ 3828 pMga->CloseScreen = pScreen->CloseScreen; 3829 pScreen->CloseScreen = MGACloseScreen; 3830 3831 /* Report any unused options (only for the first generation) */ 3832 if (serverGeneration == 1) { 3833 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 3834 } 3835 3836 /* For the second head, work around display problem. */ 3837 if (!pMga->MergedFB && pMga->SecondCrtc) { 3838 MGACrtc2FillStrip(pScrn); 3839 } 3840 3841 /* Done */ 3842 return TRUE; 3843} 3844 3845 3846/* Usually mandatory */ 3847Bool 3848MGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 3849{ 3850#ifdef USEMGAHAL 3851 char sCmdIn[256]; 3852 char sCmdOut[256]; 3853 FILE* fdIn; 3854# ifdef MATROX_WRITEBACK 3855 FILE* fdOut; 3856# endif 3857#endif 3858 3859 if (mode->Flags & 0x80000000) { 3860#ifdef USEMGAHAL 3861 3862# ifdef MATROX_WRITEBACK 3863# define MWB(x) { x; } 3864# define MWB_COND(x) x 3865# else 3866# define MWB(x) 3867# define MWB_COND(x) 1 3868# endif 3869 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 3870 3871 MGA_HAL( 3872 fdIn = fopen("/tmp/mgaDriverIn", "rt"); 3873 MWB(fdOut = fopen("/tmp/mgaDriverOut", "wt")) 3874 3875 if(fdIn && MWB_COND(fdOut)) 3876 { 3877 3878 fgets(sCmdIn, 255, fdIn); 3879 3880 if(sCmdIn) 3881 { 3882 3883 MGAExecuteEscCmd(xf86Screens[scrnIndex], sCmdIn, sCmdOut, mode); 3884 3885 /* Remove file and close file descriptor */ 3886 remove("/tmp/mgaDriverIn"); 3887 fclose(fdIn); 3888 MWB( 3889 /* Write output data to output file for 3890 calling application */ 3891 fputs(sCmdOut, fdOut); 3892 fclose(fdOut); 3893 ) 3894 mode->Flags &= 0x7FFFFFFF; 3895 return TRUE; 3896 } 3897 else 3898 { 3899 mode->Flags &= 0x7FFFFFFF; 3900 return FALSE; 3901 } 3902 } 3903 else 3904 { 3905 mode->Flags &= 0x7FFFFFFF; 3906 return FALSE; 3907 } 3908 ) 3909#endif 3910 return FALSE; 3911 } else 3912 return MGAModeInit(xf86Screens[scrnIndex], mode); 3913} 3914 3915 /* Adjusts coordinates to match Panning granularity. 3916 * does nothing if the HALlib is not loaded 3917 */ 3918void 3919MGAAdjustGranularity(ScrnInfoPtr pScrn, int* x, int* y) 3920{ 3921#ifdef USEMGAHAL 3922 MGA_HAL( 3923 MGAPtr pMga = MGAPTR(pScrn); 3924 MGAPtr pMga2; 3925 int xg = 1; 3926 int yg = 1; 3927 if(pMga->pMgaModeInfo && pMga->pMgaModeInfo->ulPanXGran && pMga->pMgaModeInfo->ulPanYGran) { 3928 xg = pMga->pMgaModeInfo->ulPanXGran; 3929 yg = pMga->pMgaModeInfo->ulPanYGran; 3930 } 3931 if(pMga->pScrn2 && (pMga2 = MGAPTR(pMga->pScrn2)) ) { 3932 3933 if(pMga2->pMgaModeInfo && pMga2->pMgaModeInfo->ulPanXGran && pMga2->pMgaModeInfo->ulPanYGran) { 3934 xg = max(xg,pMga2->pMgaModeInfo->ulPanXGran); 3935 yg = max(yg,pMga2->pMgaModeInfo->ulPanYGran); 3936 } 3937 } 3938 xg=16; /*ncoder: temporary */ 3939 *x -= *x % xg; 3940 *y -= *y % yg; 3941 ); 3942#endif 3943} 3944 3945 3946/* 3947 * This function is used to initialize the Start Address - the first 3948 * displayed location in the video memory. 3949 */ 3950/* Usually mandatory */ 3951void 3952MGAAdjustFrame(int scrnIndex, int x, int y, int flags) 3953{ 3954 ScrnInfoPtr pScrn; 3955 int Base, tmp, count; 3956 3957 MGAFBLayout *pLayout; 3958 MGAPtr pMga; 3959 3960 3961 pScrn = xf86Screens[scrnIndex]; 3962 pMga = MGAPTR(pScrn); 3963 pLayout = &pMga->CurrentLayout; 3964 3965 /* wanted to improve panning granularity problems without risking 3966 * compatibility issues. Existing code looked hardware dependent. 3967 */ 3968#ifdef USEMGAHAL 3969 MGA_HAL( 3970 pMga->HALGranularityOffX = x; 3971 pMga->HALGranularityOffY = y; 3972 MGAAdjustGranularity(pScrn,&x,&y); 3973 pMga->HALGranularityOffX = pMga->HALGranularityOffX - x; 3974 pMga->HALGranularityOffY = pMga->HALGranularityOffY - y; 3975 HALSetDisplayStart(pMga->pBoard,x,y,0); 3976 ); 3977#endif 3978 MGA_NOT_HAL( 3979 if(pMga->ShowCache && y && pScrn->vtSema) 3980 y += pScrn->virtualY - 1; 3981 3982 Base = (y * pLayout->displayWidth + x + pMga->YDstOrg) >> 3983 (3 - pMga->BppShifts[(pLayout->bitsPerPixel >> 3) - 1]); 3984 3985 if (pLayout->bitsPerPixel == 24) { 3986 if (pMga->Chipset == PCI_CHIP_MGAG400 3987 || pMga->Chipset == PCI_CHIP_MGAG550) 3988 Base &= ~1; /*1 Not sure why */ 3989 3990 Base *= 3; 3991 } 3992 3993 /* find start of retrace */ 3994 while (INREG8(0x1FDA) & 0x08); 3995 while (!(INREG8(0x1FDA) & 0x08)); 3996 /* wait until we're past the start (fixseg.c in the DDK) */ 3997 count = INREG(MGAREG_VCOUNT) + 2; 3998 while(INREG(MGAREG_VCOUNT) < count); 3999 4000 OUTREG16(MGAREG_CRTC_INDEX, (Base & 0x00FF00) | 0x0C); 4001 OUTREG16(MGAREG_CRTC_INDEX, ((Base & 0x0000FF) << 8) | 0x0D); 4002 OUTREG8(MGAREG_CRTCEXT_INDEX, 0x00); 4003 tmp = INREG8(MGAREG_CRTCEXT_DATA); 4004 OUTREG8(MGAREG_CRTCEXT_DATA, (tmp & 0xF0) | ((Base & 0x0F0000) >> 16)); 4005 ); 4006 4007} 4008 4009void 4010MGAAdjustFrameCrtc2(int scrnIndex, int x, int y, int flags) 4011{ 4012 ScrnInfoPtr pScrn; 4013 int Base; 4014 MGAFBLayout *pLayout; 4015 MGAPtr pMga; 4016 4017 pScrn = xf86Screens[scrnIndex]; 4018 pMga = MGAPTR(pScrn); 4019 pLayout = &pMga->CurrentLayout; 4020#ifdef USEMGAHAL 4021 MGA_HAL( 4022 MGAAdjustGranularity(pScrn,&x,&y); 4023 HALSetDisplayStart(pMga->pBoard,x,y,1); 4024 ); 4025#endif 4026 MGA_NOT_HAL( 4027 if(pMga->ShowCache && y && pScrn->vtSema) 4028 y += pScrn->virtualY - 1; 4029 4030 /* 3-85 c2offset 4031 * 3-93 c2startadd0 4032 * 3-96 c2vcount 4033 */ 4034 4035 Base = (y * pLayout->displayWidth + x) * pLayout->bitsPerPixel >> 3; 4036 Base += pMga->DstOrg; 4037 Base &= 0x01ffffc0; 4038 OUTREG(MGAREG_C2STARTADD0, Base); 4039 ); 4040} 4041 4042/* 4043 * This is called when VT switching back to the X server. Its job is 4044 * to reinitialise the video mode. 4045 * 4046 * We may wish to unmap video/MMIO memory too. 4047 */ 4048 4049/* Mandatory */ 4050static Bool 4051MGAEnterVT(int scrnIndex, int flags) 4052{ 4053 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 4054 MGAPtr pMga; 4055 4056 pMga = MGAPTR(pScrn); 4057 4058#ifdef XF86DRI 4059 if (pMga->directRenderingEnabled) { 4060 if (pMga->irq) { 4061 /* Need to make sure interrupts are enabled */ 4062 OUTREG(MGAREG_IEN, pMga->reg_ien); 4063 } 4064 DRIUnlock(screenInfo.screens[scrnIndex]); 4065 } 4066#endif 4067 4068 if (!MGAModeInit(pScrn, pScrn->currentMode)) 4069 return FALSE; 4070 pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 4071 4072 /* For the second head, work around display problem. */ 4073 if (pMga->SecondCrtc) { 4074 MGACrtc2FillStrip(pScrn); 4075 } 4076 4077 return TRUE; 4078} 4079 4080static Bool 4081MGAEnterVTFBDev(int scrnIndex, int flags) 4082{ 4083 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 4084#ifdef XF86DRI 4085 ScreenPtr pScreen; 4086 MGAPtr pMga; 4087 4088 pMga = MGAPTR(pScrn); 4089 if (pMga->directRenderingEnabled) { 4090 pScreen = screenInfo.screens[scrnIndex]; 4091 DRIUnlock(pScreen); 4092 } 4093#endif 4094 4095 fbdevHWEnterVT(scrnIndex,flags); 4096 MGAStormEngineInit(pScrn); 4097 return TRUE; 4098} 4099 4100#define RESTORE_TEXTMODE_ON_DVI(x) \ 4101 if (MGAISGx50(x) && \ 4102 (ISDIGITAL1(x) || ISDIGITAL2(x))) { \ 4103 /* Reset DUALDVI register */ \ 4104 outMGAdac(MGA1064_DVI_PIPE_CTL, 0x0); \ 4105 /* Set Panel mode between 20 and 54 MHz */ \ 4106 outMGAdac(MGA1064_PAN_CTL, 0x7); \ 4107 } 4108 4109 4110/* 4111 * This is called when VT switching away from the X server. Its job is 4112 * to restore the previous (text) mode. 4113 * 4114 * We may wish to remap video/MMIO memory too. 4115 */ 4116 4117/* Mandatory */ 4118static void 4119MGALeaveVT(int scrnIndex, int flags) 4120{ 4121 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 4122 vgaHWPtr hwp = VGAHWPTR(pScrn); 4123#ifdef XF86DRI 4124 MGAPtr pMga = MGAPTR(pScrn); 4125 ScreenPtr pScreen; 4126#endif 4127 4128 MGARestore(pScrn); 4129 vgaHWLock(hwp); 4130 4131 if (xf86IsPc98()) 4132 outb(0xfac, 0x00); 4133#ifdef XF86DRI 4134 if (pMga->directRenderingEnabled) { 4135 pScreen = screenInfo.screens[scrnIndex]; 4136 DRILock(pScreen, 0); 4137 } 4138#endif 4139#ifdef USEMGAHAL 4140 MGA_HAL( RESTORE_TEXTMODE_ON_DVI(pMga); ); 4141#endif 4142} 4143 4144 4145/* 4146 * This is called at the end of each server generation. It restores the 4147 * original (text) mode. It should also unmap the video memory, and free 4148 * any per-generation data allocated by the driver. It should finish 4149 * by unwrapping and calling the saved CloseScreen function. 4150 */ 4151 4152/* Mandatory */ 4153static Bool 4154MGACloseScreen(int scrnIndex, ScreenPtr pScreen) 4155{ 4156 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 4157 vgaHWPtr hwp = VGAHWPTR(pScrn); 4158 MGAPtr pMga = MGAPTR(pScrn); 4159 MGAEntPtr pMgaEnt = NULL; 4160 4161#ifdef USEMGAHAL 4162 MGA_HAL( RESTORE_TEXTMODE_ON_DVI(pMga); ); 4163#endif 4164 if (pMga->MergedFB) 4165 MGACloseScreenMerged(scrnIndex, pScreen); 4166 4167 if (pScrn->vtSema) { 4168 if (pMga->FBDev) { 4169 fbdevHWRestore(pScrn); 4170 MGAUnmapMem(pScrn); 4171 } else { 4172 MGARestore(pScrn); 4173 vgaHWLock(hwp); 4174 MGAUnmapMem(pScrn); 4175 vgaHWUnmapMem(pScrn); 4176 } 4177 } 4178#ifdef XF86DRI 4179 if (pMga->directRenderingEnabled) { 4180 MGADRICloseScreen(pScreen); 4181 pMga->directRenderingEnabled=FALSE; 4182 } 4183#endif 4184 4185 if (pMga->DualHeadEnabled) { 4186 DevUnion *pPriv; 4187 pPriv = xf86GetEntityPrivate(pScrn->entityList[0], MGAEntityIndex); 4188 pMgaEnt = pPriv->ptr; 4189 pMgaEnt->refCount--; 4190 } 4191 4192#ifdef USEMGAHAL 4193 MGA_HAL( 4194 if(pMga->DualHeadEnabled) { 4195 if(pMgaEnt->refCount == 0) { 4196 /* Both boards have closed there screen */ 4197 MGACloseLibrary(pMga->pBoard); 4198 4199 if (pMga->pBoard) 4200 xfree(pMga->pBoard); 4201 if (pMga->pClientStruct) 4202 xfree(pMga->pClientStruct); 4203 if (pMga->pMgaModeInfo) 4204 xfree(pMga->pMgaModeInfo); 4205 if (pMga->pMgaHwInfo) 4206 xfree(pMga->pMgaHwInfo); 4207 } 4208 } else { 4209 MGACloseLibrary(pMga->pBoard); 4210 4211 if (pMga->pBoard) 4212 xfree(pMga->pBoard); 4213 if (pMga->pClientStruct) 4214 xfree(pMga->pClientStruct); 4215 if (pMga->pMgaModeInfo) 4216 xfree(pMga->pMgaModeInfo); 4217 if (pMga->pMgaHwInfo) 4218 xfree(pMga->pMgaHwInfo); 4219 } 4220 ); /* MGA_HAL */ 4221#endif 4222 4223#ifdef USE_XAA 4224 if (pMga->AccelInfoRec) 4225 XAADestroyInfoRec(pMga->AccelInfoRec); 4226#endif 4227#ifdef USE_EXA 4228 if (pMga->ExaDriver) { 4229 exaDriverFini(pScreen); 4230 xfree(pMga->ExaDriver); 4231 } 4232#endif 4233 if (pMga->CursorInfoRec) 4234 xf86DestroyCursorInfoRec(pMga->CursorInfoRec); 4235 if (pMga->ShadowPtr) 4236 xfree(pMga->ShadowPtr); 4237 if (pMga->DGAModes) 4238 xfree(pMga->DGAModes); 4239 if (pMga->adaptor) 4240 xfree(pMga->adaptor); 4241 if (pMga->portPrivate) 4242 xfree(pMga->portPrivate); 4243 if (pMga->ScratchBuffer) 4244 xfree(pMga->ScratchBuffer); 4245 4246 pScrn->vtSema = FALSE; 4247 4248 if (xf86IsPc98()) 4249 outb(0xfac, 0x00); 4250 4251 xf86ClearPrimInitDone(pScrn->entityList[0]); 4252 4253 if(pMga->BlockHandler) 4254 pScreen->BlockHandler = pMga->BlockHandler; 4255 4256 pScreen->CloseScreen = pMga->CloseScreen; 4257 4258 return (*pScreen->CloseScreen)(scrnIndex, pScreen); 4259} 4260 4261 4262/* Free up any persistent data structures */ 4263 4264/* Optional */ 4265static void 4266MGAFreeScreen(int scrnIndex, int flags) 4267{ 4268 4269 /* 4270 * This only gets called when a screen is being deleted. It does not 4271 * get called routinely at the end of a server generation. 4272 */ 4273 if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) 4274 vgaHWFreeHWRec(xf86Screens[scrnIndex]); 4275 MGAFreeRec(xf86Screens[scrnIndex]); 4276 4277} 4278 4279 4280/* Checks if a mode is suitable for the selected chipset. */ 4281 4282/* Optional */ 4283static ModeStatus 4284MGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 4285{ 4286 int lace; 4287 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 4288 MGAPtr pMga = MGAPTR(pScrn); 4289 4290 if (pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) { 4291 if (mode->HDisplay > 1600) 4292 return MODE_VIRTUAL_X; 4293 if (mode->VDisplay > 1200) 4294 return MODE_VIRTUAL_Y; 4295 } 4296 4297 lace = 1 + ((mode->Flags & V_INTERLACE) != 0); 4298 4299 if ((mode->CrtcHDisplay <= 2048) && 4300 (mode->CrtcHSyncStart <= 4096) && 4301 (mode->CrtcHSyncEnd <= 4096) && 4302 (mode->CrtcHTotal <= 4096) && 4303 (mode->CrtcVDisplay <= 2048 * lace) && 4304 (mode->CrtcVSyncStart <= 4096 * lace) && 4305 (mode->CrtcVSyncEnd <= 4096 * lace) && 4306 (mode->CrtcVTotal <= 4096 * lace)) { 4307 4308 /* Can't have horizontal panning for second head of G400 */ 4309 if (pMga->SecondCrtc) { 4310 if (flags == MODECHECK_FINAL) { 4311 if (pMga->allowedWidth == 0) 4312 pMga->allowedWidth = pScrn->virtualX; 4313 if (mode->HDisplay != pMga->allowedWidth) 4314 return(MODE_ONE_WIDTH); 4315 } 4316 } 4317 4318 return(MODE_OK); 4319 } else { 4320 return(MODE_BAD); 4321 } 4322} 4323 4324 4325/* 4326 * This routine is required but since we can't easily blank the 4327 * second display without risking powering off the monitor, return 4328 * FALSE and let the X server do something generic. 4329 */ 4330static Bool 4331MGASaveScreenCrtc2(ScreenPtr pScreen, int mode) 4332{ 4333 return FALSE; 4334} 4335 4336/* Do screen blanking */ 4337 4338static Bool 4339MGASaveScreen(ScreenPtr pScreen, int mode) 4340{ 4341 return vgaHWSaveScreen(pScreen, mode); 4342} 4343 4344 4345/* 4346 * MGADisplayPowerManagementSet -- 4347 * 4348 * Sets VESA Display Power Management Signaling (DPMS) Mode. 4349 * 4350 * XXX This needs fixing for sync-on-green! 4351 */ 4352void 4353MGADisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, 4354 int flags) 4355{ 4356 MGAPtr pMga = MGAPTR(pScrn); 4357 unsigned char seq1 = 0, crtcext1 = 0; 4358 4359 switch (PowerManagementMode) 4360 { 4361 case DPMSModeOn: 4362 /* Screen: On; HSync: On, VSync: On */ 4363 seq1 = 0x00; 4364 crtcext1 = 0x00; 4365 break; 4366 case DPMSModeStandby: 4367 /* Screen: Off; HSync: Off, VSync: On */ 4368 seq1 = 0x20; 4369 crtcext1 = 0x10; 4370 break; 4371 case DPMSModeSuspend: 4372 /* Screen: Off; HSync: On, VSync: Off */ 4373 seq1 = 0x20; 4374 crtcext1 = 0x20; 4375 break; 4376 case DPMSModeOff: 4377 /* Screen: Off; HSync: Off, VSync: Off */ 4378 seq1 = 0x20; 4379 crtcext1 = 0x30; 4380 break; 4381 } 4382 4383 /* XXX Prefer an implementation that doesn't depend on VGA specifics */ 4384 OUTREG8(MGAREG_SEQ_INDEX, 0x01); /* Select SEQ1 */ 4385 seq1 |= INREG8(MGAREG_SEQ_DATA) & ~0x20; 4386 MGAWAITVSYNC(); 4387 MGAWAITBUSY(); 4388 OUTREG8(MGAREG_SEQ_DATA, seq1); 4389 usleep(20000); 4390 OUTREG8(MGAREG_CRTCEXT_INDEX, 0x01); /* Select CRTCEXT1 */ 4391 crtcext1 |= INREG8(MGAREG_CRTCEXT_DATA) & ~0x30; 4392 OUTREG8(MGAREG_CRTCEXT_DATA, crtcext1); 4393} 4394 4395 4396void 4397MGADisplayPowerManagementSetCrtc2(ScrnInfoPtr pScrn, int PowerManagementMode, 4398 int flags) 4399{ 4400 MGAPtr pMga = MGAPTR(pScrn); 4401 CARD32 val = INREG(MGAREG_C2CTL); 4402 4403 if (PowerManagementMode==DPMSModeOn) { 4404 /* Enable CRTC2 */ 4405 val |= MGAREG_C2CTL_C2_EN; 4406 val &= ~MGAREG_C2CTL_PIXCLKDIS_DISABLE; 4407 OUTREG(MGAREG_C2CTL, val); 4408 /* Restore normal MAVEN values */ 4409 if (pMga->Maven) { 4410 /* if TV MODE -- for later implementation 4411 MAVW(MONEN, 0xb3); 4412 MAVW(MONSET, 0x20); 4413 MAVW(OUTMODE, 0x08); output: SVideo/Composite 4414 MAVW(STABLE, 0x02); makes picture stable? 4415 fixme? linux uses 0x14... 4416 MAVW(TEST, (MAVR(TEST) & 0x10)); 4417 4418 */ 4419 /* else monitor mode */ 4420 4421 xf86I2CWriteByte(pMga->Maven, MGAMAV_MONEN, 0xb2); 4422 /* must be set to this in monitor mode */ 4423 xf86I2CWriteByte(pMga->Maven, MGAMAV_MONSET, 0x20); 4424 /* output: monitor mode */ 4425 xf86I2CWriteByte(pMga->Maven, MGAMAV_OUTMODE, 0x03); 4426 /* makes picture stable? */ 4427 xf86I2CWriteByte(pMga->Maven, MGAMAV_STABLE, 0x22); 4428 /* turn off test signal */ 4429 xf86I2CWriteByte(pMga->Maven, MGAMAV_TEST, 0x00); 4430 } 4431 } 4432 else { 4433 /* Disable CRTC2 video */ 4434 val |= MGAREG_C2CTL_PIXCLKDIS_DISABLE; 4435 val &= ~MGAREG_C2CTL_C2_EN; 4436 OUTREG(MGAREG_C2CTL, val); 4437 4438 /* Disable MAVEN display */ 4439 if (pMga->Maven) { 4440 /* In order to blank the 2nd display, we must set some MAVEN registers. 4441 * It seems that not always the same values work on different hardware so 4442 * we try a few different (possibly redundant) ones. */ 4443 /* xf86I2CWriteByte(pMga->Maven, MGAMAV_STABLE, 0x6a); */ 4444 /* xf86I2CWriteByte(pMga->Maven, MGAMAV_TEST, 0x03); */ 4445 /* xf86I2CWriteByte(pMga->Maven, MGAMAV_TEST, 0x10); */ 4446 xf86I2CWriteByte(pMga->Maven, MGAMAV_OUTMODE, 0x80); 4447 } 4448 4449 } 4450} 4451 4452 4453static void 4454MGABlockHandler ( 4455 int i, 4456 pointer blockData, 4457 pointer pTimeout, 4458 pointer pReadmask 4459){ 4460 ScreenPtr pScreen = screenInfo.screens[i]; 4461 ScrnInfoPtr pScrn = xf86Screens[i]; 4462 MGAPtr pMga = MGAPTR(pScrn); 4463 4464 if(pMga->PaletteLoadCallback) 4465 (*pMga->PaletteLoadCallback)(pScrn); 4466 4467 pScreen->BlockHandler = pMga->BlockHandler; 4468 (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); 4469 pScreen->BlockHandler = MGABlockHandler; 4470 4471 if(pMga->VideoTimerCallback) { 4472 UpdateCurrentTime(); 4473 (*pMga->VideoTimerCallback)(pScrn, currentTime.milliseconds); 4474 } 4475 4476 if(pMga->RenderCallback) 4477 (*pMga->RenderCallback)(pScrn); 4478} 4479 4480#if defined (EXTRADEBUG) 4481/* 4482 * some functions to track input/output in the server 4483 */ 4484 4485CARD8 4486MGAdbg_inreg8(ScrnInfoPtr pScrn,int addr,int verbose, char* func) 4487{ 4488 CARD8 ret; 4489 4490 ret = MMIO_IN8(MGAPTR(pScrn)->IOBase,addr); 4491 if(verbose) 4492 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4493 "inreg8 : %s: 0x%8x = 0x%x\n",func, addr,ret); 4494 return ret; 4495} 4496 4497CARD16 4498MGAdbg_inreg16(ScrnInfoPtr pScrn,int addr,int verbose, char* func) 4499{ 4500 CARD16 ret; 4501 4502 ret = MMIO_IN16(MGAPTR(pScrn)->IOBase,addr); 4503 if(verbose) 4504 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4505 "inreg16: %s: 0x%8x = 0x%x\n",func, addr,ret); 4506 return ret; 4507} 4508 4509CARD32 4510MGAdbg_inreg32(ScrnInfoPtr pScrn,int addr,int verbose, char* func) 4511{ 4512 CARD32 ret; 4513 4514 ret = MMIO_IN32(MGAPTR(pScrn)->IOBase,addr); 4515 if(verbose) 4516 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4517 "inreg32: %s: 0x%8x = 0x%x\n",func, addr,ret); 4518 return ret; 4519} 4520 4521void 4522MGAdbg_outreg8(ScrnInfoPtr pScrn,int addr,int val, char* func) 4523{ 4524 CARD8 ret; 4525 4526#if 0 4527 if( addr = MGAREG_CRTCEXT_DATA ) 4528 return; 4529#endif 4530 if( addr != 0x3c00 ) { 4531 ret = MGAdbg_inreg8(pScrn,addr,0,func); 4532 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4533 "outreg8 : %s: 0x%8x = 0x%x was 0x%x\n", 4534 func,addr,val,ret); 4535 } 4536 else { 4537 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "outreg8 : %s: index 0x%x\n", 4538 func,val); 4539 } 4540 MMIO_OUT8(MGAPTR(pScrn)->IOBase,addr,val); 4541} 4542 4543void 4544MGAdbg_outreg16(ScrnInfoPtr pScrn,int addr,int val, char* func) 4545{ 4546 CARD16 ret; 4547 4548#if 0 4549 if (addr == MGAREG_CRTCEXT_INDEX) 4550 return; 4551#endif 4552 ret = MGAdbg_inreg16(pScrn,addr,0, func); 4553 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4554 "outreg16: %s: 0x%8x = 0x%x was 0x%x\n", 4555 func,addr,val,ret); 4556 MMIO_OUT16(MGAPTR(pScrn)->IOBase,addr,val); 4557} 4558 4559void 4560MGAdbg_outreg32(ScrnInfoPtr pScrn,int addr,int val, char* func) 4561{ 4562 CARD32 ret; 4563 4564 if (((addr & 0xff00) == 0x1c00) 4565 && (addr != 0x1c04) 4566/* && (addr != 0x1c1c) */ 4567 && (addr != 0x1c20) 4568 && (addr != 0x1c24) 4569 && (addr != 0x1c80) 4570 && (addr != 0x1c8c) 4571 && (addr != 0x1c94) 4572 && (addr != 0x1c98) 4573 && (addr != 0x1c9c) 4574 ) { 4575 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s: refused address 0x%x\n", 4576 func,addr); 4577 return; 4578 } 4579 ret = MGAdbg_inreg32(pScrn,addr,0, func); 4580 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4581 "outreg32: %s: 0x%8x = 0x%x was 0x%x\n", 4582 func,addr,val,ret); 4583 MMIO_OUT32(MGAPTR(pScrn)->IOBase,addr,val); 4584} 4585#endif /* DEBUG */ 4586 4587static void 4588MGAG100BlackMagic(ScrnInfoPtr pScrn) 4589{ 4590 MGAPtr pMga = MGAPTR(pScrn); 4591 4592 OUTREG(MGAREG_PLNWT, ~(CARD32)0x0); 4593 /* reset memory */ 4594 OUTREG(MGAREG_MACCESS, 1<<15); 4595 usleep(10); 4596} 4597 4598