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