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