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