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