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