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