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