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