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