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