mga_driver.c revision a31a186a
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 = 1024; 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 /* Some X compute displayWidth from inferred virtual without 2466 checking pitch limit. */ 2467 if(pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI && pScrn->videoRam < 2048) 2468 pScrn->displayWidth = 1024; 2469 2470 if (i < 1 && pMga->FBDev) { 2471 fbdevHWUseBuildinMode(pScrn); 2472 pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */ 2473 i = 1; 2474 } 2475 if (i == -1) { 2476 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Validate Modes Failed\n"); 2477 MGAFreeRec(pScrn); 2478 return FALSE; 2479 } 2480 2481 /* Prune the modes marked as invalid */ 2482 xf86PruneDriverModes(pScrn); 2483 2484 if (i == 0 || pScrn->modes == NULL) { 2485 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); 2486 MGAFreeRec(pScrn); 2487 return FALSE; 2488 } 2489#ifdef USEMGAHAL 2490 MGA_HAL( 2491 2492 if(pMga->SecondCrtc == FALSE) { 2493 2494 pMga->pBoard = xalloc(sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize()); 2495 pMga->pClientStruct = xalloc(sizeof(CLIENTDATA)); 2496 pMga->pClientStruct->pMga = (MGAPtr) pMga; 2497 2498 MGAMapMem(pScrn); 2499 /* 2500 * For some reason the MGAOPM_DMA_BLIT bit needs to be set 2501 * on G200 before opening the HALlib. I don't know why. 2502 * MATROX: hint, hint. 2503 */ 2504 /*if (pMga->Chipset == PCI_CHIP_MGAG200 || 2505 pMga->Chipset == PCI_CHIP_MGAG200_PCI) */{ 2506 CARD32 opmode; 2507 opmode = INREG(MGAREG_OPMODE); 2508 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT | opmode); 2509 } 2510 /* wrapping OpenLibrary to fix broken registers. MATROX: hint, hint. */ 2511 MiscCtlReg = inMGAdac(MGA1064_MISC_CTL); 2512 MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA)); 2513 outMGAdac(MGA1064_MISC_CTL,MiscCtlReg); 2514 MGAUnmapMem(pScrn); 2515 pMga->pMgaHwInfo = xalloc(sizeof(MGAHWINFO)); 2516 MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo); 2517 2518 /* copy the board handles */ 2519 if (pMga->DualHeadEnabled) { 2520 pMgaEnt->pClientStruct = pMga->pClientStruct; 2521 pMgaEnt->pBoard = pMga->pBoard; 2522 pMgaEnt->pMgaHwInfo = pMga->pMgaHwInfo; 2523 } 2524 2525 } else { /* Second CRTC && entity is shared */ 2526 pMga->pBoard = pMgaEnt->pBoard; 2527 pMga->pClientStruct = pMgaEnt->pClientStruct; 2528 pMga->pMgaHwInfo = pMgaEnt->pMgaHwInfo; 2529 2530 } 2531 2532 MGAFillModeInfoStruct(pScrn,NULL); 2533 /* Fields usually handled by MGAFillModeInfoStruct, but are unavailable 2534 * because no mode is given 2535 */ 2536 pMga->pMgaModeInfo->ulDispWidth = pScrn->virtualX; 2537 pMga->pMgaModeInfo->ulDispHeight = pScrn->virtualY; 2538 2539 2540 if (ISDIGITAL1(pMga)) 2541 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2542 "Digital screen detected on first head.\n"); 2543 if (ISTV1(pMga)) 2544 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2545 "TV detected on first head.\n"); 2546 if (ISDIGITAL2(pMga)) 2547 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2548 "Digital screen detected on second head.\n"); 2549 if (ISTV2(pMga)) 2550 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2551 "TV detected on second head.\n"); 2552 2553 2554 if((status = MGAValidateMode(pMga->pBoard,pMga->pMgaModeInfo)) != 0) { 2555 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2556 "MGAValidateMode from HALlib found the mode to be invalid.\n" 2557 "\tError: 0x%lx\n", status); 2558 return FALSE; 2559 } 2560 pScrn->displayWidth = pMga->pMgaModeInfo->ulFBPitch; 2561 ); /* MGA_HAL */ 2562#endif 2563 2564 /* If the Device section explicitly set HasSDRAM, don't bother checking. 2565 */ 2566 if (!pMga->HasSDRAM) { 2567 if ((pMga->softbooted || pMga->Primary) 2568 && pMga->chip_attribs->probe_for_sdram) { 2569 uint32_t option_reg; 2570 2571#ifdef XSERVER_LIBPCIACCESS 2572 pci_device_cfg_read_u32(pMga->PciInfo, & option_reg, 2573 PCI_OPTION_REG); 2574#else 2575 option_reg = pciReadLong(pMga->PciTag, PCI_OPTION_REG); 2576#endif 2577 pMga->HasSDRAM = ((option_reg & (1 << 14)) == 0); 2578 } 2579 else { 2580 pMga->HasSDRAM = pMga->chip_attribs->has_sdram; 2581 } 2582 2583 if (pMga->HasSDRAM) { 2584 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Has SDRAM\n"); 2585 } 2586 } 2587 2588 /* 2589 * Set the CRTC parameters for all of the modes based on the type 2590 * of mode, and the chipset's interlace requirements. 2591 * 2592 * Calling this is required if the mode->Crtc* values are used by the 2593 * driver and if the driver doesn't provide code to set them. They 2594 * are not pre-initialised at all. 2595 */ 2596#ifdef USEMGAHAL 2597 MGA_HAL(xf86SetCrtcForModes(pScrn, 0)); 2598#endif 2599 MGA_NOT_HAL(xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V)); 2600 2601 /* Set the current mode to the first in the list */ 2602 pScrn->currentMode = pScrn->modes; 2603 2604 /* Print the list of modes being used */ 2605 xf86PrintModes(pScrn); 2606 2607 /* Set display resolution */ 2608 xf86SetDpi(pScrn, 0, 0); 2609 2610 /* 2611 * Compute the byte offset into the linear frame buffer where the 2612 * frame buffer data should actually begin. According to DDK misc.c 2613 * line 1023, if more than 4MB is to be displayed, YDSTORG must be set 2614 * appropriately to align memory bank switching, and this requires a 2615 * corresponding offset on linear frame buffer access. 2616 * This is only needed for WRAM. 2617 */ 2618 2619 pMga->YDstOrg = 0; 2620 if (pMga->chip_attribs->fb_4mb_quirk && 2621 (pScrn->virtualX * pScrn->virtualY * bytesPerPixel > 4*1024*1024)) { 2622 int offset; 2623 int offset_modulo = (pScrn->bitsPerPixel == 24) ? 12 : 4; 2624 int ydstorg_modulo = 64; 2625 2626 2627 if (pMga->Interleave) { 2628 offset_modulo <<= 1; 2629 ydstorg_modulo <<= 1; 2630 } 2631 2632 offset = (4*1024*1024) % (pScrn->displayWidth * bytesPerPixel); 2633 pMga->YDstOrg = offset / bytesPerPixel; 2634 2635 /* 2636 * When this was unconditional, it caused a line of horizontal garbage 2637 * at the middle right of the screen at the 4Meg boundary in 32bpp 2638 * (and presumably any other modes that use more than 4M). But it's 2639 * essential for 24bpp (it may not matter either way for 8bpp & 16bpp, 2640 * I'm not sure; I didn't notice problems when I checked with and 2641 * without.) 2642 * DRM Doug Merritt 12/97, submitted to XFree86 6/98 (oops) 2643 */ 2644 if (bytesPerPixel < 4) { 2645 while ((offset % offset_modulo) != 0 || 2646 (pMga->YDstOrg % ydstorg_modulo) != 0) { 2647 offset++; 2648 pMga->YDstOrg = offset / bytesPerPixel; 2649 } 2650 } 2651 } 2652 2653 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "YDstOrg is set to %d\n", 2654 pMga->YDstOrg); 2655 if(pMga->DualHeadEnabled) { 2656 if(pMga->SecondCrtc == FALSE) { 2657 pMga->FbUsableSize = pMgaEnt->masterFbMapSize; 2658 /* Allocate HW cursor buffer at the end of video ram */ 2659 if( pMga->HWCursor && pMga->Dac.CursorOffscreenMemSize ) { 2660 if( pScrn->virtualY * pScrn->displayWidth * 2661 pScrn->bitsPerPixel / 8 <= 2662 pMga->FbUsableSize - pMga->Dac.CursorOffscreenMemSize ) { 2663 pMga->FbUsableSize -= pMga->Dac.CursorOffscreenMemSize; 2664 pMga->FbCursorOffset = 2665 pMgaEnt->masterFbMapSize - 2666 pMga->Dac.CursorOffscreenMemSize; 2667 } else { 2668 pMga->HWCursor = FALSE; 2669 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2670 "Too little offscreen memory for HW cursor; " 2671 "using SW cursor\n"); 2672 } 2673 } 2674 } else { /* Second CRTC */ 2675 pMga->FbUsableSize = pMgaEnt->slaveFbMapSize; 2676 pMga->HWCursor = FALSE; 2677 } 2678 } else { 2679 pMga->FbUsableSize = pMga->FbMapSize - pMga->YDstOrg * bytesPerPixel; 2680 /* Allocate HW cursor buffer at the end of video ram */ 2681 if( pMga->HWCursor && pMga->Dac.CursorOffscreenMemSize ) { 2682 if( pScrn->virtualY * pScrn->displayWidth * 2683 pScrn->bitsPerPixel / 8 <= 2684 pMga->FbUsableSize - pMga->Dac.CursorOffscreenMemSize ) { 2685 pMga->FbUsableSize -= pMga->Dac.CursorOffscreenMemSize; 2686 pMga->FbCursorOffset = 2687 pMga->FbMapSize - pMga->Dac.CursorOffscreenMemSize; 2688 } else { 2689 pMga->HWCursor = FALSE; 2690 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2691 "Too little offscreen memory for HW cursor; " 2692 "using SW cursor\n"); 2693 } 2694 } 2695 } 2696 /* 2697 * XXX This should be taken into account in some way in the mode valdation 2698 * section. 2699 */ 2700 2701 2702 /* Load the required framebuffer */ 2703 if (!xf86LoadSubModule(pScrn, "fb")) { 2704 MGAFreeRec(pScrn); 2705 return FALSE; 2706 } 2707 2708 /* Load XAA if needed */ 2709 if (!pMga->NoAccel) { 2710#ifdef USE_EXA 2711 if (pMga->Exa) { 2712 if (!xf86LoadSubModule(pScrn, "exa")) { 2713 MGAFreeRec(pScrn); 2714 return FALSE; 2715 } 2716 } else { 2717#endif 2718#ifdef USE_XAA 2719 if (!xf86LoadSubModule(pScrn, "xaa")) { 2720 MGAFreeRec(pScrn); 2721 return FALSE; 2722 } 2723#endif 2724#ifdef USE_EXA 2725 } 2726#endif 2727 } 2728 2729 /* Load ramdac if needed */ 2730 if (pMga->HWCursor) { 2731 if (!xf86LoadSubModule(pScrn, "ramdac")) { 2732 MGAFreeRec(pScrn); 2733 return FALSE; 2734 } 2735 } 2736 2737 /* Load shadowfb if needed */ 2738 if (pMga->ShadowFB) { 2739 if (!xf86LoadSubModule(pScrn, "shadowfb")) { 2740 MGAFreeRec(pScrn); 2741 return FALSE; 2742 } 2743 } 2744 2745#ifdef XF86DRI 2746 /* Load the dri module if requested. */ 2747 if (xf86ReturnOptValBool(pMga->Options, OPTION_DRI, FALSE)) { 2748 xf86LoadSubModule(pScrn, "dri"); 2749 } 2750#endif 2751 pMga->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel; 2752 pMga->CurrentLayout.depth = pScrn->depth; 2753 pMga->CurrentLayout.displayWidth = pScrn->displayWidth; 2754 pMga->CurrentLayout.weight.red = pScrn->weight.red; 2755 pMga->CurrentLayout.weight.green = pScrn->weight.green; 2756 pMga->CurrentLayout.weight.blue = pScrn->weight.blue; 2757 pMga->CurrentLayout.mode = pScrn->currentMode; 2758 2759 2760 2761 if(pMga->MergedFB) { 2762 MGAPreInitMergedFB(pScrn,flags); 2763 }; 2764 2765 2766#ifdef USEMGAHAL 2767 MGA_HAL( 2768 /* Close the library after preinit */ 2769 /* This needs to only happen after this board has completed preinit 2770 * both times 2771 */ 2772 2773 if(pMga->DualHeadEnabled) { 2774 /* Entity is shared make sure refcount == 2 */ 2775 /* If ref count is 2 then reset it to 0 */ 2776 if(pMgaEnt->refCount == 2) { 2777 /* Both boards have done there initialization */ 2778 MGACloseLibrary(pMga->pBoard); 2779 2780 if (pMga->pBoard) 2781 xfree(pMga->pBoard); 2782 if (pMga->pClientStruct) 2783 xfree(pMga->pClientStruct); 2784 if (pMga->pMgaModeInfo) 2785 xfree(pMga->pMgaModeInfo); 2786 if (pMga->pMgaHwInfo) 2787 xfree(pMga->pMgaHwInfo); 2788 pMgaEnt->refCount = 0; 2789 } 2790 } else { 2791 MGACloseLibrary(pMga->pBoard); 2792 2793 if (pMga->pBoard) 2794 xfree(pMga->pBoard); 2795 if (pMga->pClientStruct) 2796 xfree(pMga->pClientStruct); 2797 if (pMga->pMgaModeInfo) 2798 xfree(pMga->pMgaModeInfo); 2799 if (pMga->pMgaHwInfo) 2800 xfree(pMga->pMgaHwInfo); 2801 } 2802 2803 ); /* MGA_HAL */ 2804#endif 2805 2806 xf86SetPrimInitDone(pScrn->entityList[0]); 2807 2808 return TRUE; 2809} 2810 2811 2812/* 2813 * Map the framebuffer and MMIO memory. 2814 */ 2815 2816static Bool 2817MGAMapMem(ScrnInfoPtr pScrn) 2818{ 2819 MGAPtr pMga = MGAPTR(pScrn); 2820#ifdef XSERVER_LIBPCIACCESS 2821 struct pci_device *const dev = pMga->PciInfo; 2822 struct pci_mem_region *region; 2823 void **memory[2]; 2824 int i, err; 2825#endif 2826 2827 2828 if (!pMga->FBDev) { 2829#ifdef XSERVER_LIBPCIACCESS 2830 memory[pMga->io_bar] = &pMga->IOBase; 2831 memory[pMga->framebuffer_bar] = &pMga->FbBase; 2832 2833 for (i = 0; i < 2; i++) { 2834 region = &dev->regions[i]; 2835 err = pci_device_map_range(dev, 2836 region->base_addr, region->size, 2837 PCI_DEV_MAP_FLAG_WRITABLE, 2838 memory[i]); 2839 2840 if (err) { 2841 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2842 "Unable to map BAR %i. %s (%d)\n", 2843 i, strerror(err), err); 2844 return FALSE; 2845 } 2846 } 2847#else 2848 /* 2849 * For Alpha, we need to map SPARSE memory, since we need 2850 * byte/short access. This is taken care of automatically by the 2851 * os-support layer. 2852 */ 2853 pMga->IOBase = xf86MapPciMem(pScrn->scrnIndex, 2854 VIDMEM_MMIO | VIDMEM_READSIDEEFFECT, 2855 pMga->PciTag, pMga->IOAddress, 0x4000); 2856 if (pMga->IOBase == NULL) 2857 return FALSE; 2858 2859 pMga->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 2860 pMga->PciTag, pMga->FbAddress, 2861 pMga->FbMapSize); 2862 if (pMga->FbBase == NULL) 2863 return FALSE; 2864#endif 2865 } 2866 else { 2867 pMga->FbBase = fbdevHWMapVidmem(pScrn); 2868 if (pMga->FbBase == NULL) { 2869 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2870 "Unable to map framebuffer.\n"); 2871 return FALSE; 2872 } 2873 2874 pMga->IOBase = fbdevHWMapMMIO(pScrn); 2875 if (pMga->IOBase == NULL) { 2876 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to map MMIO.\n"); 2877 return FALSE; 2878 } 2879 } 2880 2881 2882 pMga->FbStart = pMga->FbBase + pMga->YDstOrg * (pScrn->bitsPerPixel / 8); 2883 2884 pMga->ILOADBase = NULL; 2885 if (pMga->iload_bar != -1) { 2886#ifdef XSERVER_LIBPCIACCESS 2887 region = &dev->regions[pMga->iload_bar]; 2888 err = pci_device_map_range(dev, 2889 region->base_addr, region->size, 2890 PCI_DEV_MAP_FLAG_WRITABLE, 2891 (void *) &pMga->ILOADBase); 2892 if (err) { 2893 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2894 "Unable to map BAR 2 (ILOAD region). %s (%d)\n", 2895 strerror(err), err); 2896 return FALSE; 2897 } 2898#else 2899 pMga->ILOADBase = xf86MapPciMem(pScrn->scrnIndex, 2900 VIDMEM_MMIO | VIDMEM_MMIO_32BIT | 2901 VIDMEM_READSIDEEFFECT, 2902 pMga->PciTag, pMga->ILOADAddress, 2903 0x800000); 2904#endif 2905 } 2906 2907 2908 return TRUE; 2909} 2910 2911 2912/* 2913 * Unmap the framebuffer and MMIO memory. 2914 */ 2915 2916static Bool 2917MGAUnmapMem(ScrnInfoPtr pScrn) 2918{ 2919 MGAPtr pMga = MGAPTR(pScrn); 2920#ifdef XSERVER_LIBPCIACCESS 2921 struct pci_device * const dev = pMga->PciInfo; 2922#endif 2923 2924 2925 if (!pMga->FBDev) { 2926#ifdef XSERVER_LIBPCIACCESS 2927 pci_device_unmap_range(dev, pMga->IOBase, 2928 dev->regions[pMga->io_bar].size); 2929 pci_device_unmap_range(dev, pMga->FbBase, 2930 dev->regions[pMga->framebuffer_bar].size); 2931#else 2932 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->IOBase, 0x4000); 2933 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->FbBase, pMga->FbMapSize); 2934#endif 2935 } 2936 else { 2937 fbdevHWUnmapVidmem(pScrn); 2938 fbdevHWUnmapMMIO(pScrn); 2939 } 2940 2941 if ((pMga->iload_bar != -1) && (pMga->ILOADBase != NULL)) { 2942#ifdef XSERVER_LIBPCIACCESS 2943 pci_device_unmap_range(dev, pMga->ILOADBase, 2944 dev->regions[pMga->iload_bar].size); 2945#else 2946 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->ILOADBase, 0x800000); 2947#endif 2948 } 2949 2950 pMga->IOBase = NULL; 2951 pMga->FbBase = NULL; 2952 pMga->FbStart = NULL; 2953 pMga->ILOADBase = NULL; 2954 2955 return TRUE; 2956} 2957 2958 2959/* 2960 * This function saves the video state. 2961 */ 2962static void 2963MGASave(ScrnInfoPtr pScrn) 2964{ 2965 vgaHWPtr hwp = VGAHWPTR(pScrn); 2966 vgaRegPtr vgaReg = &hwp->SavedReg; 2967 MGAPtr pMga = MGAPTR(pScrn); 2968 MGARegPtr mgaReg = &pMga->SavedReg; 2969 2970 if(pMga->SecondCrtc == TRUE) return; 2971#ifdef USEMGAHAL 2972 MGA_HAL(if (pMga->pBoard != NULL) MGASaveVgaState(pMga->pBoard)); 2973#endif 2974 2975 /* I need to save the registers for the second head also */ 2976 /* Save the register for 0x80 to 0xa0 */ 2977 /* Could call it dac2Saved */ 2978 2979 /* Only save text mode fonts/text for the primary card */ 2980 (*pMga->Save)(pScrn, vgaReg, mgaReg, pMga->Primary); 2981} 2982 2983#ifdef USEMGAHAL 2984/* Convert DisplayModeRec parameters in MGAMODEINFO parameters. 2985* mode parameter optionnal. */ 2986void 2987MGAFillModeInfoStruct(ScrnInfoPtr pScrn, DisplayModePtr mode) 2988{ 2989 const char *s; 2990 MGAPtr pMga = MGAPTR(pScrn); 2991 2992 Bool digital1 = FALSE; 2993 Bool digital2 = FALSE; 2994 Bool tv1 = FALSE; 2995 Bool tv2 = FALSE; 2996 Bool swap_head 2997 = xf86ReturnOptValBool(pMga->Options, OPTION_SWAPPED_HEAD, FALSE); 2998 2999 if(pMga->MergedFB && mode && mode->Private && (mode->PrivSize == 0)) { 3000 mode = pMga->SecondCrtc ? 3001 ((MergedDisplayModePtr)mode->Private)->Monitor2 3002 : ((MergedDisplayModePtr)mode->Private)->Monitor1; 3003 } 3004 3005 3006 if (pMga->pMgaHwInfo) 3007 { 3008 digital1 = ISDIGITAL1(pMga); 3009 digital2 = ISDIGITAL2(pMga); 3010 tv1 = ISTV1(pMga); 3011 tv2 = ISTV2(pMga); 3012 } 3013 3014 /*FIXME: causes segfault elsewhere if not commented*/ 3015 /*if(!pMga->pMgaModeInfo)*/ pMga->pMgaModeInfo = xalloc(sizeof(MGAMODEINFO)); 3016 pMga->pMgaModeInfo->flOutput = 0; 3017 pMga->pMgaModeInfo->ulDeskWidth = pScrn->virtualX; 3018 pMga->pMgaModeInfo->ulDeskHeight = pScrn->virtualY; 3019 pMga->pMgaModeInfo->ulFBPitch = 0; 3020 pMga->pMgaModeInfo->ulBpp = pScrn->bitsPerPixel; 3021 pMga->pMgaModeInfo->ulZoom = 1; 3022 pMga->pMgaModeInfo->flSignalMode = 0x10; 3023 3024 /* Set TV standard */ 3025 if ((s = xf86GetOptValString(pMga->Options, OPTION_TVSTANDARD))) { 3026 if (!xf86NameCmp(s, "PAL")) { 3027 pMga->pMgaModeInfo->flSignalMode = 0x00; 3028 pMga->pMgaModeInfo->ulRefreshRate = 50; 3029 pMga->pMgaModeInfo->ulTVStandard = TV_PAL; 3030 } else { 3031 pMga->pMgaModeInfo->ulRefreshRate = 60; 3032 pMga->pMgaModeInfo->ulTVStandard = TV_NTSC; 3033 } 3034 } else { 3035 pMga->pMgaModeInfo->ulRefreshRate = 0; 3036 pMga->pMgaModeInfo->ulTVStandard = TV_NTSC; 3037 } 3038 3039 /* Set Cable Type */ 3040 if ((s = xf86GetOptValString(pMga->Options, OPTION_CABLETYPE))) { 3041 if (!xf86NameCmp(s, "SCART_RGB")) { 3042 pMga->pMgaModeInfo->ulCableType = TV_SCART_RGB; 3043 } else if (!xf86NameCmp(s, "SCART_COMPOSITE")) { 3044 pMga->pMgaModeInfo->ulCableType = TV_SCART_COMPOSITE; 3045 } else if (!xf86NameCmp(s, "SCART_TYPE2")) { 3046 pMga->pMgaModeInfo->ulCableType = TV_SCART_TYPE2; 3047 } else { 3048 pMga->pMgaModeInfo->ulCableType = TV_YC_COMPOSITE; 3049 } 3050 } else { 3051 pMga->pMgaModeInfo->ulCableType = TV_YC_COMPOSITE; 3052 } 3053 3054 if(mode) { 3055 pMga->pMgaModeInfo->ulHorizRate = 0; 3056 pMga->pMgaModeInfo->ulDispWidth = mode->HDisplay; 3057 pMga->pMgaModeInfo->ulDispHeight = mode->VDisplay; 3058 pMga->pMgaModeInfo->ulPixClock = mode->Clock; 3059 pMga->pMgaModeInfo->ulHFPorch = mode->HSyncStart - mode->HDisplay; 3060 pMga->pMgaModeInfo->ulHSync = mode->HSyncEnd - mode->HSyncStart; 3061 pMga->pMgaModeInfo->ulHBPorch = mode->HTotal - mode->HSyncEnd; 3062 pMga->pMgaModeInfo->ulVFPorch = mode->VSyncStart - mode->VDisplay; 3063 pMga->pMgaModeInfo->ulVSync = mode->VSyncEnd - mode->VSyncStart; 3064 pMga->pMgaModeInfo->ulVBPorch = mode->VTotal - mode->VSyncEnd; 3065 } 3066 /* Use DstOrg directly */ 3067 /* This is an offset in pixels not memory */ 3068 pMga->pMgaModeInfo->ulDstOrg = pMga->DstOrg / (pScrn->bitsPerPixel / 8); 3069 pMga->pMgaModeInfo->ulDisplayOrg = pMga->DstOrg / (pScrn->bitsPerPixel / 8); 3070 pMga->pMgaModeInfo->ulPanXGran = 0; 3071 pMga->pMgaModeInfo->ulPanYGran = 0; 3072 3073 if(pMga->SecondCrtc == TRUE) { 3074 pMga->pMgaModeInfo->flOutput = MGAMODEINFO_SECOND_CRTC | 3075 MGAMODEINFO_FORCE_PITCH | 3076 MGAMODEINFO_FORCE_DISPLAYORG; 3077 if (digital2) { 3078 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_DIGITAL2; 3079 } else if (tv2) { 3080 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_TV; 3081 } else { 3082 if (!swap_head) { 3083 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG2; 3084 } else { 3085 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG1; 3086 } 3087 } 3088 } else { 3089 pMga->pMgaModeInfo->flOutput = MGAMODEINFO_FORCE_PITCH; 3090 if (digital1) { 3091 if ((pMga->Chipset == PCI_CHIP_MGAG200) || 3092 (pMga->Chipset == PCI_CHIP_MGAG200_PCI)) { 3093 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_FLATPANEL1; 3094 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_DIGITAL2; 3095 } else { 3096 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_DIGITAL1; 3097 } 3098 } else if (tv1) { 3099 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_TV; 3100 } else { 3101 if (!swap_head) { 3102 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG1; 3103 } else { 3104 pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_ANALOG2; 3105 } 3106 } 3107 } 3108 pMga->pMgaModeInfo->ulFBPitch = pScrn->displayWidth; 3109} 3110#endif 3111 3112/* 3113 * Initialise a new mode. This is currently still using the old 3114 * "initialise struct, restore/write struct to HW" model. That could 3115 * be changed. 3116 */ 3117 3118static Bool 3119MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 3120{ 3121 vgaHWPtr hwp = VGAHWPTR(pScrn); 3122 vgaRegPtr vgaReg; 3123 MGAPtr pMga = MGAPTR(pScrn); 3124 MGARegPtr mgaReg; 3125 3126#ifdef USEMGAHAL 3127 ULONG status; 3128#endif 3129 vgaHWUnlock(hwp); 3130 3131/* if(pMga->MergedFB && mode && mode->Private && (mode->PrivSize == 0)) { 3132 mode = (DisplayModePtr)mode->Private; 3133 }*/ 3134 3135 /* Initialise the ModeReg values */ 3136 if (!vgaHWInit(pScrn, mode)) 3137 return FALSE; 3138 pScrn->vtSema = TRUE; 3139 3140 if (!(*pMga->ModeInit)(pScrn, mode)) 3141 return FALSE; 3142 3143 /* Program the registers */ 3144 if (pMga->is_G200SE) { 3145 MGAG200SEHWProtect(pScrn, TRUE); 3146 } else { 3147 vgaHWProtect(pScrn, TRUE); 3148 } 3149 vgaReg = &hwp->ModeReg; 3150 mgaReg = &pMga->ModeReg; 3151#ifdef USEMGAHAL 3152 MGA_HAL( 3153 MGAFillModeInfoStruct(pScrn,mode); 3154 3155 /* Validate the parameters */ 3156 if ((status = MGAValidateMode(pMga->pBoard, pMga->pMgaModeInfo)) != 0) { 3157 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3158 "MGAValidateMode from HALlib found the mode to be invalid.\n" 3159 "\tError: %lx\n", status); 3160 return FALSE; 3161 } 3162 3163 /* 3164 * Find mode for second head. 3165 */ 3166 if(pMga->MergedFB) { 3167 3168 MGAFillModeInfoStruct(pMga->pScrn2,mode); 3169 /* Validates the Video parameters */ 3170 if ((status = MGAValidateVideoParameters(pMga->pBoard, MGAPTR(pMga->pScrn2)->pMgaModeInfo)) 3171 != 0) { 3172 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3173 "MGAValidateVideoParameters from HALlib found the mode to be invalid.\n\tError: %lx\n", status); 3174 return FALSE; 3175 } 3176 } 3177 ); /*MGA_HAL */ 3178 3179#endif 3180 3181#ifdef USEMGAHAL 3182MGA_HAL( 3183 3184 /*************************** ESC *****************************/ 3185 TmpMgaModeInfo[0] = *pMga->pMgaModeInfo; 3186 3187 if(pMga->SecondCrtc == TRUE) 3188 pMgaModeInfo[1] = pMga->pMgaModeInfo; 3189 else 3190 pMgaModeInfo[0] = pMga->pMgaModeInfo; 3191 3192 TmpMgaModeInfo[0].ulDispWidth = 0; 3193 3194 if(!pMga->MergedFB) /* FIXME: Must deal with this once PowerDesk & MergedFB 3195 compatibility will exist */ 3196 MGAFillDisplayModeStruct(mode, pMga->pMgaModeInfo); 3197 /*************************************************************/ 3198 3199); /* MGA_HAL */ 3200#endif 3201 3202#ifdef XF86DRI 3203 if (pMga->directRenderingEnabled) { 3204 DRILock(screenInfo.screens[pScrn->scrnIndex], 0); 3205 } 3206#endif 3207 3208#ifdef USEMGAHAL 3209 MGA_HAL( 3210 /* Initialize the board */ 3211 if(MGASetMode(pMga->pBoard,pMga->pMgaModeInfo) != 0) { 3212 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3213 "MGASetMode returned an error." 3214 " Make sure to validate the mode before.\n"); 3215 return FALSE; 3216 } 3217 if(pMga->MergedFB 3218 && MGASetMode(pMga->pBoard,MGAPTR(pMga->pScrn2)->pMgaModeInfo) != 0) { 3219 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3220 "MGASetMode returned an error." 3221 " Make sure to validate the mode before.\n"); 3222 } 3223 3224 ); /* MGA_HAL */ 3225 3226 /* getting around bugs in the HAL lib. MATROX: hint, hint. */ 3227 MGA_HAL( 3228 if (pMga->chip_attribs->hwcursor_1064) { 3229 if(pMga->SecondCrtc == FALSE && pMga->HWCursor == TRUE) { 3230 outMGAdac(MGA1064_CURSOR_BASE_ADR_LOW, 3231 pMga->FbCursorOffset >> 10); 3232 outMGAdac(MGA1064_CURSOR_BASE_ADR_HI, 3233 pMga->FbCursorOffset >> 18); 3234 outMGAdac(MGA1064_CURSOR_CTL, 0x00); 3235 } 3236 } 3237 ); /* MGA_HAL */ 3238#endif 3239 3240 MGA_NOT_HAL((*pMga->Restore)(pScrn, vgaReg, mgaReg, FALSE)); 3241 3242 MGAStormSync(pScrn); 3243 MGAStormEngineInit(pScrn); 3244 3245 if (pMga->is_G200SE) { 3246 MGAG200SEHWProtect(pScrn,FALSE); 3247 } else { 3248 vgaHWProtect(pScrn, FALSE); 3249 } 3250 3251 if (xf86IsPc98()) { 3252 if (pMga->Chipset == PCI_CHIP_MGA2064) 3253 outb(0xfac, 0x01); 3254 else 3255 outb(0xfac, 0x02); 3256 } 3257 3258 MGA_NOT_HAL( 3259 if (pMga->is_G200SE) { 3260 OUTREG8(0x1FDE, 0x06); 3261 if (pMga->reg_1e24 == 0x01) 3262 OUTREG8(0x1FDF, 0x03); 3263 else 3264 OUTREG8(0x1FDF, 0x14); 3265 } 3266 ); 3267 3268 pMga->CurrentLayout.mode = mode; 3269 3270 if(pMga->MergedFB && mode->Private && (mode->PrivSize == 0)) { 3271 pMga->M1currentMode = (DisplayModePtr)mode->Private; 3272 } 3273 3274#ifdef XF86DRI 3275 if (pMga->directRenderingEnabled) 3276 DRIUnlock(screenInfo.screens[pScrn->scrnIndex]); 3277#endif 3278#ifdef DEBUG 3279 MGAG450PrintPLL(pScrn); 3280#endif 3281 return TRUE; 3282} 3283 3284static 3285void MGARestoreSecondCrtc(ScrnInfoPtr pScrn) 3286{ 3287 MGAPtr pMga = MGAPTR(pScrn); 3288 3289 if (MGAISGx50(pMga)) { 3290 /* Force to return in clone mode */ 3291 if (pMga->SecondOutput 3292 && (xf86IsEntityShared(pScrn->entityList[0]) || pMga->SecondCrtc) 3293 && !pMga->MergedFB) { 3294 /* Do this branch if 3295 * SecondOutput 3296 * and not Unshared Primary 3297 * and not Merged Mode (usualy means Unshared Primary) 3298 */ 3299 CARD8 ucXDispCtrl = inMGAdac(MGA1064_DISP_CTL); 3300 3301 ucXDispCtrl &= ~MGA1064_DISP_CTL_DAC2OUTSEL_MASK; 3302 ucXDispCtrl |= MGA1064_DISP_CTL_DAC2OUTSEL_CRTC1; 3303 3304 outMGAdac(MGA1064_DISP_CTL, ucXDispCtrl); 3305 3306 } else { 3307 CARD8 ucXDispCtrl = inMGAdac(MGA1064_DISP_CTL); 3308 CARD32 ulC2CTL = INREG(MGAREG_C2CTL); 3309 3310 ucXDispCtrl &= ~MGA1064_DISP_CTL_DAC2OUTSEL_MASK; 3311 ucXDispCtrl |= MGA1064_DISP_CTL_DAC1OUTSEL_EN; 3312 ucXDispCtrl |= MGA1064_DISP_CTL_DAC2OUTSEL_CRTC1; 3313 3314 /* crtcdacsel -> crtc1 */ 3315 ulC2CTL &= ~MGAREG_C2CTL_CRTCDACSEL_CRTC2; 3316 ulC2CTL |= MGAREG_C2CTL_CRTCDACSEL_CRTC1; 3317 3318 outMGAdac(MGA1064_DISP_CTL, ucXDispCtrl); 3319 OUTREG(MGAREG_C2CTL, ulC2CTL); 3320 } 3321 3322 } else { 3323 /* Force to close second crtc */ 3324 CARD32 ulC2CTL = INREG(MGAREG_C2CTL); 3325 3326 ulC2CTL &= ~MGAREG_C2CTL_C2_EN; 3327 3328 OUTREG(MGAREG_C2CTL, ulC2CTL); 3329 } 3330} 3331 3332/* 3333 * Restore the initial (text) mode. 3334 */ 3335static void 3336MGARestore(ScrnInfoPtr pScrn) 3337{ 3338 vgaHWPtr hwp = VGAHWPTR(pScrn); 3339 vgaRegPtr vgaReg = &hwp->SavedReg; 3340 MGAPtr pMga = MGAPTR(pScrn); 3341 MGARegPtr mgaReg = &pMga->SavedReg; 3342 3343 if (pScrn->pScreen != NULL) 3344 MGAStormSync(pScrn); 3345 3346 /* 3347 * Restore the second crtc if: 3348 * first and only driver entity 3349 * second entity 3350 * Merged Framebuffer mode (first and only driver entity) 3351 */ 3352 if((!xf86IsEntityShared(pScrn->entityList[0]) && !pMga->SecondCrtc) 3353 || pMga->SecondCrtc || pMga->MergedFB) { 3354 /* if(pMga->MergedFB) { 3355 if(pMga->pScrn2) 3356 MGARestoreSecondCrtc(pMga->pScrn2); 3357 } else*/ 3358 MGARestoreSecondCrtc(pScrn); 3359 /* if we are second instance of driver, we've done our job, exit */ 3360 if(pMga->SecondCrtc) return; 3361 } 3362 3363 /* Only restore text mode fonts/text for the primary card */ 3364 if (pMga->is_G200SE) { 3365 MGAG200SEHWProtect(pScrn,TRUE); 3366 } else { 3367 vgaHWProtect(pScrn, TRUE); 3368 } 3369 if (pMga->Primary) { 3370#ifdef USEMGAHAL 3371 MGA_HAL( 3372 if(pMga->pBoard != NULL) { 3373 MGASetVgaMode(pMga->pBoard); 3374 MGARestoreVgaState(pMga->pBoard); 3375 } 3376 ); /* MGA_HAL */ 3377#endif 3378 (*pMga->Restore)(pScrn, vgaReg, mgaReg, TRUE); 3379 } else { 3380 vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); 3381 } 3382 3383 if (pMga->is_G200SE) { 3384 MGAG200SEHWProtect(pScrn,FALSE); 3385 } else { 3386 vgaHWProtect(pScrn,FALSE); 3387 } 3388} 3389 3390 3391/* Workaround for a G400 CRTC2 display problem */ 3392static void 3393MGACrtc2FillStrip(ScrnInfoPtr pScrn) 3394{ 3395 MGAPtr pMga = MGAPTR(pScrn); 3396 3397 if (pMga->NoAccel) { 3398 /* Clears the whole screen, but ... */ 3399 bzero(pMga->FbStart, 3400 (pScrn->bitsPerPixel >> 3) * pScrn->displayWidth * pScrn->virtualY); 3401 } else { 3402 xf86SetLastScrnFlag(pScrn->entityList[0], pScrn->scrnIndex); 3403 pMga->RestoreAccelState(pScrn); 3404 pMga->SetupForSolidFill(pScrn, 0, GXcopy, 0xFFFFFFFF); 3405 pMga->SubsequentSolidFillRect(pScrn, pScrn->virtualX, 0, 3406 pScrn->displayWidth - pScrn->virtualX, 3407 pScrn->virtualY); 3408 MGAStormSync(pScrn); 3409 } 3410} 3411 3412 3413/* Mandatory */ 3414 3415/* This gets called at the start of each server generation */ 3416 3417static Bool 3418MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 3419{ 3420 ScrnInfoPtr pScrn; 3421 vgaHWPtr hwp; 3422 MGAPtr pMga; 3423 MGARamdacPtr MGAdac; 3424 int ret; 3425 VisualPtr visual; 3426 unsigned char *FBStart; 3427 int width, height, displayWidth; 3428 MGAEntPtr pMgaEnt = NULL; 3429 int f; 3430 CARD32 VRTemp, FBTemp; 3431#ifdef XF86DRI 3432 MessageType driFrom = X_DEFAULT; 3433#endif 3434 DPMSSetProcPtr mga_dpms_set_proc = NULL; 3435 3436 /* 3437 * First get the ScrnInfoRec 3438 */ 3439 pScrn = xf86Screens[pScreen->myNum]; 3440 3441 hwp = VGAHWPTR(pScrn); 3442 pMga = MGAPTR(pScrn); 3443 MGAdac = &pMga->Dac; 3444 3445 if (pMga->is_G200SE) { 3446 VRTemp = pScrn->videoRam; 3447 FBTemp = pMga->FbMapSize; 3448 pScrn->videoRam = 8192; 3449 pMga->FbMapSize = pScrn->videoRam * 1024; 3450 } 3451 3452 3453 /* Map the MGA memory and MMIO areas */ 3454 if (!MGAMapMem(pScrn)) 3455 return FALSE; 3456 3457 3458 /* Select functions that vary based on the CRTC configureation of the 3459 * screen. 3460 */ 3461 if (!pMga->MergedFB) { 3462 if (pMga->SecondCrtc) { 3463 mga_dpms_set_proc = MGADisplayPowerManagementSetCrtc2; 3464 pScreen->SaveScreen = MGASaveScreenCrtc2; 3465 } 3466 else { 3467 mga_dpms_set_proc = MGADisplayPowerManagementSet; 3468 pScreen->SaveScreen = MGASaveScreen; 3469 } 3470 } 3471 else { 3472 pScreen->SaveScreen = MGASaveScreenMerged; 3473 mga_dpms_set_proc = MGADisplayPowerManagementSetMerged; 3474 } 3475 3476 3477 if ((pMga->Chipset == PCI_CHIP_MGAG100) 3478 || (pMga->Chipset == PCI_CHIP_MGAG100_PCI)) 3479 MGAG100BlackMagic(pScrn); 3480 3481 if (pMga->DualHeadEnabled) { 3482 DevUnion *pPriv; 3483 pPriv = xf86GetEntityPrivate(pScrn->entityList[0], MGAEntityIndex); 3484 pMgaEnt = pPriv->ptr; 3485 pMgaEnt->refCount++; 3486#ifdef USEMGAHAL 3487 MGA_HAL( 3488 if(pMgaEnt->refCount == 1) { 3489 CARD8 MiscCtlReg; 3490 pMga->pBoard = xalloc(sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize()); 3491 pMga->pClientStruct = xalloc(sizeof(CLIENTDATA)); 3492 pMga->pClientStruct->pMga = (MGAPtr) pMga; 3493 3494 /* wrapping OpenLibrary to fix broken registers. MATROX: hint,hint.*/ 3495 MiscCtlReg = inMGAdac(MGA1064_MISC_CTL); 3496 MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA)); 3497 outMGAdac(MGA1064_MISC_CTL,MiscCtlReg); 3498 pMga->pMgaHwInfo = xalloc(sizeof(MGAHWINFO)); 3499 MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo); 3500 3501 /* Detecting for type of display */ 3502 if (pMga->pMgaHwInfo->ulCapsSecondOutput & MGAHWINFOCAPS_OUTPUT_TV) { 3503 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "TV detected\n"); 3504 } 3505 if (pMga->pMgaHwInfo->ulCapsFirstOutput & 3506 MGAHWINFOCAPS_OUTPUT_DIGITAL) { 3507 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3508 "Digital Screen detected\n"); 3509 } 3510 if (pMga->pMgaHwInfo->ulCapsSecondOutput & 3511 MGAHWINFOCAPS_OUTPUT_DIGITAL) { 3512 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 3513 "Digital Screen detected\n"); 3514 } 3515 3516 /* Now copy these to the entitystructure */ 3517 pMgaEnt->pClientStruct = pMga->pClientStruct; 3518 pMgaEnt->pBoard = pMga->pBoard; 3519 pMgaEnt->pMgaHwInfo = pMga->pMgaHwInfo; 3520 } else { /* Ref count is 2 */ 3521 pMga->pClientStruct = pMgaEnt->pClientStruct; 3522 pMga->pBoard = pMgaEnt->pBoard; 3523 pMga->pMgaHwInfo = pMgaEnt->pMgaHwInfo; 3524 } 3525 ); /* MGA_HAL */ 3526#endif 3527 } else { 3528#ifdef USEMGAHAL 3529 CARD8 MiscCtlReg; 3530 3531 MGA_HAL( 3532 pMga->pBoard = xalloc(sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize()); 3533 pMga->pClientStruct = xalloc(sizeof(CLIENTDATA)); 3534 pMga->pClientStruct->pMga = (MGAPtr) pMga; 3535 3536 MiscCtlReg = inMGAdac(MGA1064_MISC_CTL); 3537 /* wrapping OpenLibrary to fix broken registers. MATROX: hint,hint.*/ 3538 MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA)); 3539 outMGAdac(MGA1064_MISC_CTL,MiscCtlReg); 3540 pMga->pMgaHwInfo = xalloc(sizeof(MGAHWINFO)); 3541 MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo); 3542 ); /* MGA_HAL */ 3543#endif 3544 } 3545 if (pMga->is_G200SE) { 3546 pScrn->videoRam = VRTemp; 3547 pMga->FbMapSize = FBTemp; 3548 } 3549#ifdef USEMGAHAL 3550 MGA_HAL( 3551 /* There is a problem in the HALlib: set soft reset bit */ 3552 /* MATROX: hint, hint. */ 3553 if (!pMga->Primary && !pMga->FBDev && 3554 (SUBSYS_ID(pMga->PciInfo) == PCI_CARD_MILL_G200_SG)) { 3555 OUTREG(MGAREG_Reset, 1); 3556 usleep(200); 3557 OUTREG(MGAREG_Reset, 0); 3558 } 3559 ); /* MGA_HAL */ 3560#endif 3561 3562 /* Initialise the MMIO vgahw functions */ 3563 vgaHWSetMmioFuncs(hwp, pMga->IOBase, PORT_OFFSET); 3564 vgaHWGetIOBase(hwp); 3565 3566 /* Map the VGA memory when the primary video */ 3567 if (!pMga->FBDev) { 3568 if (pMga->Primary) { 3569 hwp->MapSize = 0x10000; 3570 if (!vgaHWMapMem(pScrn)) 3571 return FALSE; 3572 } 3573 3574 /* Save the current state */ 3575 MGASave(pScrn); 3576 /* Initialise the first mode */ 3577 if (!MGAModeInit(pScrn, pScrn->currentMode)) 3578 return FALSE; 3579 } 3580 else { 3581 fbdevHWSave(pScrn); 3582 /* Disable VGA core, and leave memory access on */ 3583#ifdef XSERVER_LIBPCIACCESS 3584 pci_device_cfg_write_bits(pMga->PciInfo, 0x00000100, 0x00000000, 3585 PCI_OPTION_REG); 3586#else 3587 pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, 0x100, 0x000); 3588#endif 3589 if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) 3590 return FALSE; 3591 3592 if (!pMga->SecondCrtc && pMga->HWCursor 3593 && pMga->chip_attribs->hwcursor_1064) { 3594 outMGAdac(MGA1064_CURSOR_BASE_ADR_LOW, pMga->FbCursorOffset >> 10); 3595 outMGAdac(MGA1064_CURSOR_BASE_ADR_HI, pMga->FbCursorOffset >> 18); 3596 } 3597 3598 MGAStormEngineInit(pScrn); 3599 } 3600 3601 /* Darken the screen for aesthetic reasons and set the viewport 3602 */ 3603 (*pScreen->SaveScreen)(pScreen, SCREEN_SAVER_ON); 3604 pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 3605 3606 3607 /* 3608 * The next step is to setup the screen's visuals, and initialise the 3609 * framebuffer code. In cases where the framebuffer's default 3610 * choices for things like visual layouts and bits per RGB are OK, 3611 * this may be as simple as calling the framebuffer's ScreenInit() 3612 * function. If not, the visuals will need to be setup before calling 3613 * a fb ScreenInit() function and fixed up after. 3614 * 3615 * For most PC hardware at depths >= 8, the defaults that cfb uses 3616 * are not appropriate. In this driver, we fixup the visuals after. 3617 */ 3618 3619 /* 3620 * Reset the visual list. 3621 */ 3622 miClearVisualTypes(); 3623 3624 /* Setup the visuals we support. */ 3625 3626 /* All MGA support DirectColor */ 3627 if (pMga->SecondCrtc) { 3628 /* No DirectColor on the second head */ 3629 if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits, 3630 TrueColor)) 3631 return FALSE; 3632 if (!miSetPixmapDepths ()) 3633 return FALSE; 3634 } else { 3635 if (!xf86SetDefaultVisual(pScrn, -1)) 3636 return FALSE; 3637 3638 if (!miSetVisualTypes(pScrn->depth, 3639 miGetDefaultVisualMask(pScrn->depth), 3640 pScrn->rgbBits, pScrn->defaultVisual)) 3641 return FALSE; 3642 if (!miSetPixmapDepths ()) 3643 return FALSE; 3644 } 3645 3646 /* 3647 * Call the framebuffer layer's ScreenInit function, and fill in other 3648 * pScreen fields. 3649 */ 3650 3651 width = pScrn->virtualX; 3652 height = pScrn->virtualY; 3653 displayWidth = pScrn->displayWidth; 3654 3655 3656 if(pMga->Rotate) { 3657 height = pScrn->virtualX; 3658 width = pScrn->virtualY; 3659 } 3660 3661 if(pMga->ShadowFB) { 3662 pMga->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); 3663 pMga->ShadowPtr = xalloc(pMga->ShadowPitch * height); 3664 displayWidth = pMga->ShadowPitch / (pScrn->bitsPerPixel >> 3); 3665 FBStart = pMga->ShadowPtr; 3666 } else { 3667 pMga->ShadowPtr = NULL; 3668 FBStart = pMga->FbStart; 3669 } 3670 3671#ifdef XF86DRI 3672 /* 3673 * Setup DRI after visuals have been established. 3674 * 3675 * The DRI does not work when textured video is enabled at this time. 3676 */ 3677 if (pMga->is_G200SE) { 3678 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 3679 "Not supported by hardware, not initializing the DRI\n"); 3680 pMga->directRenderingEnabled = FALSE; 3681 driFrom = X_PROBED; 3682 } else if (!xf86ReturnOptValBool(pMga->Options, OPTION_DRI, TRUE)) { 3683 driFrom = X_CONFIG; 3684 } else if ( pMga->NoAccel ) { 3685 xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 3686 "Acceleration disabled, not initializing the DRI\n" ); 3687 pMga->directRenderingEnabled = FALSE; 3688 driFrom = X_CONFIG; 3689 } 3690 else if ( pMga->TexturedVideo == TRUE ) { 3691 xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 3692 "Textured video enabled, not initializing the DRI\n" ); 3693 pMga->directRenderingEnabled = FALSE; 3694 driFrom = X_CONFIG; 3695 } 3696 else if (pMga->SecondCrtc == TRUE) { 3697 xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 3698 "Not initializing the DRI on the second head\n" ); 3699 pMga->directRenderingEnabled = FALSE; 3700 } 3701 else if ((pMga->FbMapSize / 3702 (width * (pScrn->bitsPerPixel >> 3))) <= height * 3) { 3703 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3704 "Static buffer allocation failed, not initializing the DRI\n"); 3705 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3706 "Need at least %d kB video memory at this resolution, bit depth\n", 3707 (3 * displayWidth * height * (pScrn->bitsPerPixel >> 3)) / 1024 ); 3708 pMga->directRenderingEnabled = FALSE; 3709 driFrom = X_PROBED; 3710 } 3711 else { 3712 pMga->directRenderingEnabled = MGADRIScreenInit(pScreen); 3713 } 3714#endif 3715 3716 3717 if (!fbScreenInit(pScreen, FBStart, width, height, pScrn->xDpi, 3718 pScrn->yDpi, displayWidth, pScrn->bitsPerPixel)) { 3719 return FALSE; 3720 } 3721 3722 3723 if (pScrn->bitsPerPixel > 8) { 3724 /* Fixup RGB ordering */ 3725 visual = pScreen->visuals + pScreen->numVisuals; 3726 while (--visual >= pScreen->visuals) { 3727 if ((visual->class | DynamicClass) == DirectColor) { 3728 visual->offsetRed = pScrn->offset.red; 3729 visual->offsetGreen = pScrn->offset.green; 3730 visual->offsetBlue = pScrn->offset.blue; 3731 visual->redMask = pScrn->mask.red; 3732 visual->greenMask = pScrn->mask.green; 3733 visual->blueMask = pScrn->mask.blue; 3734 } 3735 } 3736 } 3737 3738 /* must be after RGB ordering fixed */ 3739 fbPictureInit (pScreen, 0, 0); 3740 3741 xf86SetBlackWhitePixels(pScreen); 3742 3743 pMga->BlockHandler = pScreen->BlockHandler; 3744 pScreen->BlockHandler = MGABlockHandler; 3745 3746 if(!pMga->ShadowFB) /* hardware cursor needs to wrap this layer */ 3747 MGADGAInit(pScreen); 3748 3749 if (!pMga->NoAccel) { 3750#ifdef USE_EXA 3751 if (pMga->Exa) 3752 mgaExaInit(pScreen); 3753 else 3754#endif 3755#ifdef USE_XAA 3756 MGAStormAccelInit(pScreen); 3757#endif 3758 } 3759 3760 miInitializeBackingStore(pScreen); 3761 xf86SetBackingStore(pScreen); 3762 xf86SetSilkenMouse(pScreen); 3763 3764 /* Initialize software cursor. 3765 Must precede creation of the default colormap */ 3766 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 3767 3768 /* Initialize HW cursor layer. 3769 Must follow software cursor initialization*/ 3770 if (pMga->HWCursor) { 3771 if(!MGAHWCursorInit(pScreen)) 3772 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 3773 "Hardware cursor initialization failed\n"); 3774 } 3775 if(pMga->MergedFB) { 3776 /* Rotate and MergedFB are mutiualy exclusive, so we can use this 3777 * variable. 3778 */ 3779 if (!pMga->PointerMoved) 3780 pMga->PointerMoved = pScrn->PointerMoved; 3781 pScrn->PointerMoved = MGAMergePointerMoved; 3782 3783 } 3784 3785 /* Initialise default colourmap */ 3786 if (!miCreateDefColormap(pScreen)) 3787 return FALSE; 3788 3789 /* Initialize colormap layer. 3790 Must follow initialization of the default colormap */ 3791 if (!pMga->SecondCrtc) 3792 f = CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH; 3793 else 3794 f = CMAP_RELOAD_ON_MODE_SWITCH; 3795 if(!xf86HandleColormaps(pScreen, 256, 8, 3796 pMga->FBDev ? fbdevHWLoadPaletteWeak() : MGAdac->LoadPalette, 3797 NULL, f)) 3798 return FALSE; 3799 3800 if(pMga->ShadowFB) { 3801 RefreshAreaFuncPtr refreshArea = MGARefreshArea; 3802 3803 if(pMga->Rotate) { 3804 if (!pMga->PointerMoved) { 3805 pMga->PointerMoved = pScrn->PointerMoved; 3806 pScrn->PointerMoved = MGAPointerMoved; 3807 } 3808 3809 switch(pScrn->bitsPerPixel) { 3810 case 8: refreshArea = MGARefreshArea8; break; 3811 case 16: refreshArea = MGARefreshArea16; break; 3812 case 24: refreshArea = MGARefreshArea24; break; 3813 case 32: refreshArea = MGARefreshArea32; break; 3814 } 3815 } 3816 3817 ShadowFBInit(pScreen, refreshArea); 3818 } 3819 3820 xf86DPMSInit(pScreen, mga_dpms_set_proc, 0); 3821 3822 pScrn->memPhysBase = pMga->FbAddress; 3823 pScrn->fbOffset = pMga->YDstOrg * (pScrn->bitsPerPixel / 8); 3824 3825 MGAInitVideo(pScreen); 3826 3827#ifdef XF86DRI 3828 if (pMga->directRenderingEnabled) { 3829 /* Now that mi, drm and others have done their thing, 3830 * complete the DRI setup. 3831 */ 3832 pMga->directRenderingEnabled = MGADRIFinishScreenInit(pScreen); 3833 } 3834 if (pMga->directRenderingEnabled) { 3835 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); 3836 } else { 3837 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Direct rendering disabled\n"); 3838 } 3839 if (pMga->DualHeadEnabled && pMga->SecondCrtc == FALSE) 3840 pMgaEnt->directRenderingEnabled = pMga->directRenderingEnabled; 3841 pMga->haveQuiescense = 1; 3842#endif 3843 3844 /* Wrap the current CloseScreen function */ 3845 pMga->CloseScreen = pScreen->CloseScreen; 3846 pScreen->CloseScreen = MGACloseScreen; 3847 3848 /* Report any unused options (only for the first generation) */ 3849 if (serverGeneration == 1) { 3850 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 3851 } 3852 3853 /* For the second head, work around display problem. */ 3854 if (!pMga->MergedFB && pMga->SecondCrtc) { 3855 MGACrtc2FillStrip(pScrn); 3856 } 3857 3858 /* Done */ 3859 return TRUE; 3860} 3861 3862 3863/* Usually mandatory */ 3864Bool 3865MGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 3866{ 3867#ifdef USEMGAHAL 3868 char sCmdIn[256]; 3869 char sCmdOut[256]; 3870 FILE* fdIn; 3871# ifdef MATROX_WRITEBACK 3872 FILE* fdOut; 3873# endif 3874#endif 3875 3876 if (mode->Flags & 0x80000000) { 3877#ifdef USEMGAHAL 3878 3879# ifdef MATROX_WRITEBACK 3880# define MWB(x) { x; } 3881# define MWB_COND(x) x 3882# else 3883# define MWB(x) 3884# define MWB_COND(x) 1 3885# endif 3886 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 3887 3888 MGA_HAL( 3889 fdIn = fopen("/tmp/mgaDriverIn", "rt"); 3890 MWB(fdOut = fopen("/tmp/mgaDriverOut", "wt")) 3891 3892 if(fdIn && MWB_COND(fdOut)) 3893 { 3894 3895 fgets(sCmdIn, 255, fdIn); 3896 3897 if(sCmdIn) 3898 { 3899 3900 MGAExecuteEscCmd(xf86Screens[scrnIndex], sCmdIn, sCmdOut, mode); 3901 3902 /* Remove file and close file descriptor */ 3903 remove("/tmp/mgaDriverIn"); 3904 fclose(fdIn); 3905 MWB( 3906 /* Write output data to output file for 3907 calling application */ 3908 fputs(sCmdOut, fdOut); 3909 fclose(fdOut); 3910 ) 3911 mode->Flags &= 0x7FFFFFFF; 3912 return TRUE; 3913 } 3914 else 3915 { 3916 mode->Flags &= 0x7FFFFFFF; 3917 return FALSE; 3918 } 3919 } 3920 else 3921 { 3922 mode->Flags &= 0x7FFFFFFF; 3923 return FALSE; 3924 } 3925 ) 3926#endif 3927 return FALSE; 3928 } else 3929 return MGAModeInit(xf86Screens[scrnIndex], mode); 3930} 3931 3932 /* Adjusts coordinates to match Panning granularity. 3933 * does nothing if the HALlib is not loaded 3934 */ 3935void 3936MGAAdjustGranularity(ScrnInfoPtr pScrn, int* x, int* y) 3937{ 3938#ifdef USEMGAHAL 3939 MGA_HAL( 3940 MGAPtr pMga = MGAPTR(pScrn); 3941 MGAPtr pMga2; 3942 int xg = 1; 3943 int yg = 1; 3944 if(pMga->pMgaModeInfo && pMga->pMgaModeInfo->ulPanXGran && pMga->pMgaModeInfo->ulPanYGran) { 3945 xg = pMga->pMgaModeInfo->ulPanXGran; 3946 yg = pMga->pMgaModeInfo->ulPanYGran; 3947 } 3948 if(pMga->pScrn2 && (pMga2 = MGAPTR(pMga->pScrn2)) ) { 3949 3950 if(pMga2->pMgaModeInfo && pMga2->pMgaModeInfo->ulPanXGran && pMga2->pMgaModeInfo->ulPanYGran) { 3951 xg = max(xg,pMga2->pMgaModeInfo->ulPanXGran); 3952 yg = max(yg,pMga2->pMgaModeInfo->ulPanYGran); 3953 } 3954 } 3955 xg=16; /*ncoder: temporary */ 3956 *x -= *x % xg; 3957 *y -= *y % yg; 3958 ); 3959#endif 3960} 3961 3962 3963/* 3964 * This function is used to initialize the Start Address - the first 3965 * displayed location in the video memory. 3966 */ 3967/* Usually mandatory */ 3968void 3969MGAAdjustFrame(int scrnIndex, int x, int y, int flags) 3970{ 3971 ScrnInfoPtr pScrn; 3972 int Base, tmp, count; 3973 3974 MGAFBLayout *pLayout; 3975 MGAPtr pMga; 3976 3977 3978 pScrn = xf86Screens[scrnIndex]; 3979 pMga = MGAPTR(pScrn); 3980 pLayout = &pMga->CurrentLayout; 3981 3982 /* wanted to improve panning granularity problems without risking 3983 * compatibility issues. Existing code looked hardware dependent. 3984 */ 3985#ifdef USEMGAHAL 3986 MGA_HAL( 3987 pMga->HALGranularityOffX = x; 3988 pMga->HALGranularityOffY = y; 3989 MGAAdjustGranularity(pScrn,&x,&y); 3990 pMga->HALGranularityOffX = pMga->HALGranularityOffX - x; 3991 pMga->HALGranularityOffY = pMga->HALGranularityOffY - y; 3992 HALSetDisplayStart(pMga->pBoard,x,y,0); 3993 ); 3994#endif 3995 MGA_NOT_HAL( 3996 if(pMga->ShowCache && y && pScrn->vtSema) 3997 y += pScrn->virtualY - 1; 3998 3999 Base = (y * pLayout->displayWidth + x + pMga->YDstOrg) >> 4000 (3 - pMga->BppShifts[(pLayout->bitsPerPixel >> 3) - 1]); 4001 4002 if (pLayout->bitsPerPixel == 24) { 4003 if (pMga->Chipset == PCI_CHIP_MGAG400 4004 || pMga->Chipset == PCI_CHIP_MGAG550) 4005 Base &= ~1; /*1 Not sure why */ 4006 4007 Base *= 3; 4008 } 4009 4010 /* find start of retrace */ 4011 while (INREG8(0x1FDA) & 0x08); 4012 while (!(INREG8(0x1FDA) & 0x08)); 4013 /* wait until we're past the start (fixseg.c in the DDK) */ 4014 count = INREG(MGAREG_VCOUNT) + 2; 4015 while(INREG(MGAREG_VCOUNT) < count); 4016 4017 OUTREG16(MGAREG_CRTC_INDEX, (Base & 0x00FF00) | 0x0C); 4018 OUTREG16(MGAREG_CRTC_INDEX, ((Base & 0x0000FF) << 8) | 0x0D); 4019 OUTREG8(MGAREG_CRTCEXT_INDEX, 0x00); 4020 tmp = INREG8(MGAREG_CRTCEXT_DATA); 4021 OUTREG8(MGAREG_CRTCEXT_DATA, (tmp & 0xF0) | ((Base & 0x0F0000) >> 16)); 4022 ); 4023 4024} 4025 4026void 4027MGAAdjustFrameCrtc2(int scrnIndex, int x, int y, int flags) 4028{ 4029 ScrnInfoPtr pScrn; 4030 int Base; 4031 MGAFBLayout *pLayout; 4032 MGAPtr pMga; 4033 4034 pScrn = xf86Screens[scrnIndex]; 4035 pMga = MGAPTR(pScrn); 4036 pLayout = &pMga->CurrentLayout; 4037#ifdef USEMGAHAL 4038 MGA_HAL( 4039 MGAAdjustGranularity(pScrn,&x,&y); 4040 HALSetDisplayStart(pMga->pBoard,x,y,1); 4041 ); 4042#endif 4043 MGA_NOT_HAL( 4044 if(pMga->ShowCache && y && pScrn->vtSema) 4045 y += pScrn->virtualY - 1; 4046 4047 /* 3-85 c2offset 4048 * 3-93 c2startadd0 4049 * 3-96 c2vcount 4050 */ 4051 4052 Base = (y * pLayout->displayWidth + x) * pLayout->bitsPerPixel >> 3; 4053 Base += pMga->DstOrg; 4054 Base &= 0x01ffffc0; 4055 OUTREG(MGAREG_C2STARTADD0, Base); 4056 ); 4057} 4058 4059/* 4060 * This is called when VT switching back to the X server. Its job is 4061 * to reinitialise the video mode. 4062 * 4063 * We may wish to unmap video/MMIO memory too. 4064 */ 4065 4066/* Mandatory */ 4067static Bool 4068MGAEnterVT(int scrnIndex, int flags) 4069{ 4070 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 4071 MGAPtr pMga; 4072 4073 pMga = MGAPTR(pScrn); 4074 4075#ifdef XF86DRI 4076 if (pMga->directRenderingEnabled) { 4077 if (pMga->irq) { 4078 /* Need to make sure interrupts are enabled */ 4079 OUTREG(MGAREG_IEN, pMga->reg_ien); 4080 } 4081 DRIUnlock(screenInfo.screens[scrnIndex]); 4082 } 4083#endif 4084 4085 if (!MGAModeInit(pScrn, pScrn->currentMode)) 4086 return FALSE; 4087 pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 4088 4089 /* For the second head, work around display problem. */ 4090 if (pMga->SecondCrtc) { 4091 MGACrtc2FillStrip(pScrn); 4092 } 4093 4094 return TRUE; 4095} 4096 4097static Bool 4098MGAEnterVTFBDev(int scrnIndex, int flags) 4099{ 4100 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 4101#ifdef XF86DRI 4102 ScreenPtr pScreen; 4103 MGAPtr pMga; 4104 4105 pMga = MGAPTR(pScrn); 4106 if (pMga->directRenderingEnabled) { 4107 pScreen = screenInfo.screens[scrnIndex]; 4108 DRIUnlock(pScreen); 4109 } 4110#endif 4111 4112 fbdevHWEnterVT(scrnIndex,flags); 4113 MGAStormEngineInit(pScrn); 4114 return TRUE; 4115} 4116 4117#define RESTORE_TEXTMODE_ON_DVI(x) \ 4118 if (MGAISGx50(x) && \ 4119 (ISDIGITAL1(x) || ISDIGITAL2(x))) { \ 4120 /* Reset DUALDVI register */ \ 4121 outMGAdac(MGA1064_DVI_PIPE_CTL, 0x0); \ 4122 /* Set Panel mode between 20 and 54 MHz */ \ 4123 outMGAdac(MGA1064_PAN_CTL, 0x7); \ 4124 } 4125 4126 4127/* 4128 * This is called when VT switching away from the X server. Its job is 4129 * to restore the previous (text) mode. 4130 * 4131 * We may wish to remap video/MMIO memory too. 4132 */ 4133 4134/* Mandatory */ 4135static void 4136MGALeaveVT(int scrnIndex, int flags) 4137{ 4138 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 4139 vgaHWPtr hwp = VGAHWPTR(pScrn); 4140#ifdef XF86DRI 4141 MGAPtr pMga = MGAPTR(pScrn); 4142 ScreenPtr pScreen; 4143#endif 4144 4145 MGARestore(pScrn); 4146 vgaHWLock(hwp); 4147 4148 if (xf86IsPc98()) 4149 outb(0xfac, 0x00); 4150#ifdef XF86DRI 4151 if (pMga->directRenderingEnabled) { 4152 pScreen = screenInfo.screens[scrnIndex]; 4153 DRILock(pScreen, 0); 4154 } 4155#endif 4156#ifdef USEMGAHAL 4157 MGA_HAL( RESTORE_TEXTMODE_ON_DVI(pMga); ); 4158#endif 4159} 4160 4161 4162/* 4163 * This is called at the end of each server generation. It restores the 4164 * original (text) mode. It should also unmap the video memory, and free 4165 * any per-generation data allocated by the driver. It should finish 4166 * by unwrapping and calling the saved CloseScreen function. 4167 */ 4168 4169/* Mandatory */ 4170static Bool 4171MGACloseScreen(int scrnIndex, ScreenPtr pScreen) 4172{ 4173 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 4174 vgaHWPtr hwp = VGAHWPTR(pScrn); 4175 MGAPtr pMga = MGAPTR(pScrn); 4176 MGAEntPtr pMgaEnt = NULL; 4177 4178#ifdef USEMGAHAL 4179 MGA_HAL( RESTORE_TEXTMODE_ON_DVI(pMga); ); 4180#endif 4181 if (pMga->MergedFB) 4182 MGACloseScreenMerged(scrnIndex, pScreen); 4183 4184 if (pScrn->vtSema) { 4185 if (pMga->FBDev) { 4186 fbdevHWRestore(pScrn); 4187 MGAUnmapMem(pScrn); 4188 } else { 4189 MGARestore(pScrn); 4190 vgaHWLock(hwp); 4191 MGAUnmapMem(pScrn); 4192 vgaHWUnmapMem(pScrn); 4193 } 4194 } 4195#ifdef XF86DRI 4196 if (pMga->directRenderingEnabled) { 4197 MGADRICloseScreen(pScreen); 4198 pMga->directRenderingEnabled=FALSE; 4199 } 4200#endif 4201 4202 if (pMga->DualHeadEnabled) { 4203 DevUnion *pPriv; 4204 pPriv = xf86GetEntityPrivate(pScrn->entityList[0], MGAEntityIndex); 4205 pMgaEnt = pPriv->ptr; 4206 pMgaEnt->refCount--; 4207 } 4208 4209#ifdef USEMGAHAL 4210 MGA_HAL( 4211 if(pMga->DualHeadEnabled) { 4212 if(pMgaEnt->refCount == 0) { 4213 /* Both boards have closed there screen */ 4214 MGACloseLibrary(pMga->pBoard); 4215 4216 if (pMga->pBoard) 4217 xfree(pMga->pBoard); 4218 if (pMga->pClientStruct) 4219 xfree(pMga->pClientStruct); 4220 if (pMga->pMgaModeInfo) 4221 xfree(pMga->pMgaModeInfo); 4222 if (pMga->pMgaHwInfo) 4223 xfree(pMga->pMgaHwInfo); 4224 } 4225 } else { 4226 MGACloseLibrary(pMga->pBoard); 4227 4228 if (pMga->pBoard) 4229 xfree(pMga->pBoard); 4230 if (pMga->pClientStruct) 4231 xfree(pMga->pClientStruct); 4232 if (pMga->pMgaModeInfo) 4233 xfree(pMga->pMgaModeInfo); 4234 if (pMga->pMgaHwInfo) 4235 xfree(pMga->pMgaHwInfo); 4236 } 4237 ); /* MGA_HAL */ 4238#endif 4239 4240#ifdef USE_XAA 4241 if (pMga->AccelInfoRec) 4242 XAADestroyInfoRec(pMga->AccelInfoRec); 4243#endif 4244#ifdef USE_EXA 4245 if (pMga->ExaDriver) { 4246 exaDriverFini(pScreen); 4247 xfree(pMga->ExaDriver); 4248 } 4249#endif 4250 if (pMga->CursorInfoRec) 4251 xf86DestroyCursorInfoRec(pMga->CursorInfoRec); 4252 if (pMga->ShadowPtr) 4253 xfree(pMga->ShadowPtr); 4254 if (pMga->DGAModes) 4255 xfree(pMga->DGAModes); 4256 if (pMga->adaptor) 4257 xfree(pMga->adaptor); 4258 if (pMga->portPrivate) 4259 xfree(pMga->portPrivate); 4260 if (pMga->ScratchBuffer) 4261 xfree(pMga->ScratchBuffer); 4262 4263 pScrn->vtSema = FALSE; 4264 4265 if (xf86IsPc98()) 4266 outb(0xfac, 0x00); 4267 4268 xf86ClearPrimInitDone(pScrn->entityList[0]); 4269 4270 if(pMga->BlockHandler) 4271 pScreen->BlockHandler = pMga->BlockHandler; 4272 4273 pScreen->CloseScreen = pMga->CloseScreen; 4274 4275 return (*pScreen->CloseScreen)(scrnIndex, pScreen); 4276} 4277 4278 4279/* Free up any persistent data structures */ 4280 4281/* Optional */ 4282static void 4283MGAFreeScreen(int scrnIndex, int flags) 4284{ 4285 4286 /* 4287 * This only gets called when a screen is being deleted. It does not 4288 * get called routinely at the end of a server generation. 4289 */ 4290 if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) 4291 vgaHWFreeHWRec(xf86Screens[scrnIndex]); 4292 MGAFreeRec(xf86Screens[scrnIndex]); 4293 4294} 4295 4296#ifndef HAVE_XF86MODEBANDWIDTH 4297 4298#define MODE_BANDWIDTH MODE_BAD 4299 4300/** Calculates the memory bandwidth (in MiB/sec) of a mode. */ 4301static unsigned int 4302xf86ModeBandwidth(DisplayModePtr mode, int depth) 4303{ 4304 float a_active, a_total, active_percent, pixels_per_second; 4305 int bytes_per_pixel = (depth + 7) / 8; 4306 4307 if (!mode->HTotal || !mode->VTotal || !mode->Clock) 4308 return 0; 4309 4310 a_active = mode->HDisplay * mode->VDisplay; 4311 a_total = mode->HTotal * mode->VTotal; 4312 active_percent = a_active / a_total; 4313 pixels_per_second = active_percent * mode->Clock * 1000.0; 4314 4315 return (unsigned int)(pixels_per_second * bytes_per_pixel / (1024 * 1024)); 4316} 4317#endif 4318 4319/* Checks if a mode is suitable for the selected chipset. */ 4320 4321/* Optional */ 4322static ModeStatus 4323MGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 4324{ 4325 int lace; 4326 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 4327 MGAPtr pMga = MGAPTR(pScrn); 4328 4329 if (pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) { 4330 if (mode->HDisplay > 1600) 4331 return MODE_VIRTUAL_X; 4332 if (mode->VDisplay > 1200) 4333 return MODE_VIRTUAL_Y; 4334 if (pMga->reg_1e24 == 0x01 && 4335 xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 256) 4336 return MODE_BANDWIDTH; 4337 } else if (pMga->is_G200WB){ 4338 if (mode->Flags & V_DBLSCAN) 4339 return MODE_NO_DBLESCAN; 4340 if (pMga->KVM && mode->HDisplay > 1280) 4341 return MODE_VIRTUAL_X; 4342 if (pMga->KVM && mode->VDisplay > 1024) 4343 return MODE_VIRTUAL_Y; 4344 if (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 318.77) 4345 return MODE_BANDWIDTH; 4346 } else if (pMga->is_G200EV 4347 && (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 327)) { 4348 return MODE_BANDWIDTH; 4349 } else if (pMga->is_G200EH 4350 && (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 375)) { 4351 return MODE_BANDWIDTH; 4352 } 4353 4354 lace = 1 + ((mode->Flags & V_INTERLACE) != 0); 4355 4356 if ((mode->CrtcHDisplay <= 2048) && 4357 (mode->CrtcHSyncStart <= 4096) && 4358 (mode->CrtcHSyncEnd <= 4096) && 4359 (mode->CrtcHTotal <= 4096) && 4360 (mode->CrtcVDisplay <= 2048 * lace) && 4361 (mode->CrtcVSyncStart <= 4096 * lace) && 4362 (mode->CrtcVSyncEnd <= 4096 * lace) && 4363 (mode->CrtcVTotal <= 4096 * lace)) { 4364 4365 /* Can't have horizontal panning for second head of G400 */ 4366 if (pMga->SecondCrtc) { 4367 if (flags == MODECHECK_FINAL) { 4368 if (pMga->allowedWidth == 0) 4369 pMga->allowedWidth = pScrn->virtualX; 4370 if (mode->HDisplay != pMga->allowedWidth) 4371 return(MODE_ONE_WIDTH); 4372 } 4373 } 4374 4375 return(MODE_OK); 4376 } else { 4377 return(MODE_BAD); 4378 } 4379} 4380 4381 4382/* 4383 * This routine is required but since we can't easily blank the 4384 * second display without risking powering off the monitor, return 4385 * FALSE and let the X server do something generic. 4386 */ 4387static Bool 4388MGASaveScreenCrtc2(ScreenPtr pScreen, int mode) 4389{ 4390 return FALSE; 4391} 4392 4393/* Do screen blanking */ 4394 4395static Bool 4396MGASaveScreen(ScreenPtr pScreen, int mode) 4397{ 4398 return vgaHWSaveScreen(pScreen, mode); 4399} 4400 4401 4402/* 4403 * MGADisplayPowerManagementSet -- 4404 * 4405 * Sets VESA Display Power Management Signaling (DPMS) Mode. 4406 * 4407 * XXX This needs fixing for sync-on-green! 4408 */ 4409void 4410MGADisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, 4411 int flags) 4412{ 4413 MGAPtr pMga = MGAPTR(pScrn); 4414 unsigned char seq1 = 0, crtcext1 = 0; 4415 4416 switch (PowerManagementMode) 4417 { 4418 case DPMSModeOn: 4419 /* Screen: On; HSync: On, VSync: On */ 4420 seq1 = 0x00; 4421 crtcext1 = 0x00; 4422 break; 4423 case DPMSModeStandby: 4424 /* Screen: Off; HSync: Off, VSync: On */ 4425 seq1 = 0x20; 4426 crtcext1 = 0x10; 4427 break; 4428 case DPMSModeSuspend: 4429 /* Screen: Off; HSync: On, VSync: Off */ 4430 seq1 = 0x20; 4431 crtcext1 = 0x20; 4432 break; 4433 case DPMSModeOff: 4434 /* Screen: Off; HSync: Off, VSync: Off */ 4435 seq1 = 0x20; 4436 crtcext1 = 0x30; 4437 break; 4438 } 4439 4440 /* XXX Prefer an implementation that doesn't depend on VGA specifics */ 4441 OUTREG8(MGAREG_SEQ_INDEX, 0x01); /* Select SEQ1 */ 4442 seq1 |= INREG8(MGAREG_SEQ_DATA) & ~0x20; 4443 MGAWAITVSYNC(); 4444 MGAWAITBUSY(); 4445 OUTREG8(MGAREG_SEQ_DATA, seq1); 4446 usleep(20000); 4447 OUTREG8(MGAREG_CRTCEXT_INDEX, 0x01); /* Select CRTCEXT1 */ 4448 crtcext1 |= INREG8(MGAREG_CRTCEXT_DATA) & ~0x30; 4449 OUTREG8(MGAREG_CRTCEXT_DATA, crtcext1); 4450} 4451 4452 4453void 4454MGADisplayPowerManagementSetCrtc2(ScrnInfoPtr pScrn, int PowerManagementMode, 4455 int flags) 4456{ 4457 MGAPtr pMga = MGAPTR(pScrn); 4458 CARD32 val = INREG(MGAREG_C2CTL); 4459 4460 if (PowerManagementMode==DPMSModeOn) { 4461 /* Enable CRTC2 */ 4462 val |= MGAREG_C2CTL_C2_EN; 4463 val &= ~MGAREG_C2CTL_PIXCLKDIS_DISABLE; 4464 OUTREG(MGAREG_C2CTL, val); 4465 /* Restore normal MAVEN values */ 4466 if (pMga->Maven) { 4467 /* if TV MODE -- for later implementation 4468 MAVW(MONEN, 0xb3); 4469 MAVW(MONSET, 0x20); 4470 MAVW(OUTMODE, 0x08); output: SVideo/Composite 4471 MAVW(STABLE, 0x02); makes picture stable? 4472 fixme? linux uses 0x14... 4473 MAVW(TEST, (MAVR(TEST) & 0x10)); 4474 4475 */ 4476 /* else monitor mode */ 4477 4478 xf86I2CWriteByte(pMga->Maven, MGAMAV_MONEN, 0xb2); 4479 /* must be set to this in monitor mode */ 4480 xf86I2CWriteByte(pMga->Maven, MGAMAV_MONSET, 0x20); 4481 /* output: monitor mode */ 4482 xf86I2CWriteByte(pMga->Maven, MGAMAV_OUTMODE, 0x03); 4483 /* makes picture stable? */ 4484 xf86I2CWriteByte(pMga->Maven, MGAMAV_STABLE, 0x22); 4485 /* turn off test signal */ 4486 xf86I2CWriteByte(pMga->Maven, MGAMAV_TEST, 0x00); 4487 } 4488 } 4489 else { 4490 /* Disable CRTC2 video */ 4491 val |= MGAREG_C2CTL_PIXCLKDIS_DISABLE; 4492 val &= ~MGAREG_C2CTL_C2_EN; 4493 OUTREG(MGAREG_C2CTL, val); 4494 4495 /* Disable MAVEN display */ 4496 if (pMga->Maven) { 4497 /* In order to blank the 2nd display, we must set some MAVEN registers. 4498 * It seems that not always the same values work on different hardware so 4499 * we try a few different (possibly redundant) ones. */ 4500 /* xf86I2CWriteByte(pMga->Maven, MGAMAV_STABLE, 0x6a); */ 4501 /* xf86I2CWriteByte(pMga->Maven, MGAMAV_TEST, 0x03); */ 4502 /* xf86I2CWriteByte(pMga->Maven, MGAMAV_TEST, 0x10); */ 4503 xf86I2CWriteByte(pMga->Maven, MGAMAV_OUTMODE, 0x80); 4504 } 4505 4506 } 4507} 4508 4509 4510static void 4511MGABlockHandler ( 4512 int i, 4513 pointer blockData, 4514 pointer pTimeout, 4515 pointer pReadmask 4516){ 4517 ScreenPtr pScreen = screenInfo.screens[i]; 4518 ScrnInfoPtr pScrn = xf86Screens[i]; 4519 MGAPtr pMga = MGAPTR(pScrn); 4520 4521 if(pMga->PaletteLoadCallback) 4522 (*pMga->PaletteLoadCallback)(pScrn); 4523 4524 pScreen->BlockHandler = pMga->BlockHandler; 4525 (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); 4526 pScreen->BlockHandler = MGABlockHandler; 4527 4528 if(pMga->VideoTimerCallback) { 4529 UpdateCurrentTime(); 4530 (*pMga->VideoTimerCallback)(pScrn, currentTime.milliseconds); 4531 } 4532 4533 if(pMga->RenderCallback) 4534 (*pMga->RenderCallback)(pScrn); 4535} 4536 4537#if defined (EXTRADEBUG) 4538/* 4539 * some functions to track input/output in the server 4540 */ 4541 4542CARD8 4543MGAdbg_inreg8(ScrnInfoPtr pScrn,int addr,int verbose, char* func) 4544{ 4545 CARD8 ret; 4546 4547 ret = MMIO_IN8(MGAPTR(pScrn)->IOBase,addr); 4548 if(verbose) 4549 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4550 "inreg8 : %s: 0x%8x = 0x%x\n",func, addr,ret); 4551 return ret; 4552} 4553 4554CARD16 4555MGAdbg_inreg16(ScrnInfoPtr pScrn,int addr,int verbose, char* func) 4556{ 4557 CARD16 ret; 4558 4559 ret = MMIO_IN16(MGAPTR(pScrn)->IOBase,addr); 4560 if(verbose) 4561 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4562 "inreg16: %s: 0x%8x = 0x%x\n",func, addr,ret); 4563 return ret; 4564} 4565 4566CARD32 4567MGAdbg_inreg32(ScrnInfoPtr pScrn,int addr,int verbose, char* func) 4568{ 4569 CARD32 ret; 4570 4571 ret = MMIO_IN32(MGAPTR(pScrn)->IOBase,addr); 4572 if(verbose) 4573 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4574 "inreg32: %s: 0x%8x = 0x%x\n",func, addr,ret); 4575 return ret; 4576} 4577 4578void 4579MGAdbg_outreg8(ScrnInfoPtr pScrn,int addr,int val, char* func) 4580{ 4581 CARD8 ret; 4582 4583#if 0 4584 if( addr = MGAREG_CRTCEXT_DATA ) 4585 return; 4586#endif 4587 if( addr != 0x3c00 ) { 4588 ret = MGAdbg_inreg8(pScrn,addr,0,func); 4589 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4590 "outreg8 : %s: 0x%8x = 0x%x was 0x%x\n", 4591 func,addr,val,ret); 4592 } 4593 else { 4594 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "outreg8 : %s: index 0x%x\n", 4595 func,val); 4596 } 4597 MMIO_OUT8(MGAPTR(pScrn)->IOBase,addr,val); 4598} 4599 4600void 4601MGAdbg_outreg16(ScrnInfoPtr pScrn,int addr,int val, char* func) 4602{ 4603 CARD16 ret; 4604 4605#if 0 4606 if (addr == MGAREG_CRTCEXT_INDEX) 4607 return; 4608#endif 4609 ret = MGAdbg_inreg16(pScrn,addr,0, func); 4610 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4611 "outreg16: %s: 0x%8x = 0x%x was 0x%x\n", 4612 func,addr,val,ret); 4613 MMIO_OUT16(MGAPTR(pScrn)->IOBase,addr,val); 4614} 4615 4616void 4617MGAdbg_outreg32(ScrnInfoPtr pScrn,int addr,int val, char* func) 4618{ 4619 CARD32 ret; 4620 4621 if (((addr & 0xff00) == 0x1c00) 4622 && (addr != 0x1c04) 4623/* && (addr != 0x1c1c) */ 4624 && (addr != 0x1c20) 4625 && (addr != 0x1c24) 4626 && (addr != 0x1c80) 4627 && (addr != 0x1c8c) 4628 && (addr != 0x1c94) 4629 && (addr != 0x1c98) 4630 && (addr != 0x1c9c) 4631 ) { 4632 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s: refused address 0x%x\n", 4633 func,addr); 4634 return; 4635 } 4636 ret = MGAdbg_inreg32(pScrn,addr,0, func); 4637 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4638 "outreg32: %s: 0x%8x = 0x%x was 0x%x\n", 4639 func,addr,val,ret); 4640 MMIO_OUT32(MGAPTR(pScrn)->IOBase,addr,val); 4641} 4642#endif /* DEBUG */ 4643 4644static void 4645MGAG100BlackMagic(ScrnInfoPtr pScrn) 4646{ 4647 MGAPtr pMga = MGAPTR(pScrn); 4648 4649 OUTREG(MGAREG_PLNWT, ~(CARD32)0x0); 4650 /* reset memory */ 4651 OUTREG(MGAREG_MACCESS, 1<<15); 4652 usleep(10); 4653} 4654 4655