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