if(xf86IsEntityShared(pScrn->entityList[0])) {
if (pMga->DualHeadEnabled) {
MGAPreInit(ScrnInfoPtr pScrn, int flags){    MGAPtr pMga;    MessageType from;    int i;    double real;    int bytesPerPixel;    ClockRangePtr clockRanges;    const char *s;    int flags24;    MGAEntPtr pMgaEnt = NULL;#ifdef USEMGAHAL    MGAMODEINFO mgaModeInfo = {0};    Bool digital1 = FALSE;    Bool digital2 = FALSE;    Bool tv1 = FALSE;    Bool tv2 = FALSE;    Bool swap_head = FALSE;    ULONG status;#endif    /*     * Note: This function is only called once at server startup, and     * not at the start of each server generation.  This means that     * only things that are persistent across server generations can     * be initialised here.  xf86Screens[] is (pScrn is a pointer to one     * of these).  Privates allocated using xf86AllocateScrnInfoPrivateIndex()     * are too, and should be used for data that must persist across     * server generations.     *     * Per-generation data should be allocated with     * AllocateScreenPrivateIndex() from the ScreenInit() function.     */    /* Check the number of entities, and fail if it isn't one. */    if (pScrn->numEntities != 1)	return FALSE;    /* Allocate the MGARec driverPrivate */    if (!MGAGetRec(pScrn)) {	return FALSE;    }    pMga = MGAPTR(pScrn);    /* Set here until dri is enabled */#ifdef XF86DRI    pMga->haveQuiescense = 1;#endif    /* Get the entity, and make sure it is PCI. */    pMga->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);    if (pMga->pEnt->location.type != BUS_PCI)	return FALSE;    /* Allocate an entity private if necessary */    if (xf86IsEntityShared(pScrn->entityList[0])) {	pMgaEnt = xf86GetEntityPrivate(pScrn->entityList[0],					MGAEntityIndex)->ptr;        pMga->entityPrivate = pMgaEnt;    }    /* Set pMga->device to the relevant Device section */    pMga->device = xf86GetDevFromEntity(pScrn->entityList[0],					pScrn->entityInstanceList[0]);    if (flags & PROBE_DETECT) {	MGAProbeDDC(pScrn, pMga->pEnt->index);	return TRUE;    }    /* The vgahw module should be loaded here when needed */    if (!xf86LoadSubModule(pScrn, "vgahw"))	return FALSE;    xf86LoaderReqSymLists(vgahwSymbols, NULL);    /*     * Allocate a vgaHWRec     */    if (!vgaHWGetHWRec(pScrn))	return FALSE;    /* Find the PCI info for this screen */    pMga->PciInfo = xf86GetPciInfoForEntity(pMga->pEnt->index);    pMga->PciTag = pciTag(pMga->PciInfo->bus, pMga->PciInfo->device,			  pMga->PciInfo->func);    pMga->Primary = xf86IsPrimaryPci(pMga->PciInfo);#ifndef DISABLE_VGA_IO    { 	resRange vgaio[] =	{ {ResShrIoBlock,0x3B0,0x3BB}, 				  {ResShrIoBlock,0x3C0,0x3DF}, 				  _END }; 	resRange vga1mem[] =	{ {ResShrMemBlock,0xA0000,0xAFFFF}, 				  {ResShrMemBlock,0xB8000,0xBFFFF}, 				  _END }; 	resRange vga2mem[] =	{ {ResShrMemBlock,0xB0000,0xB7FFF}, 				  _END }; 	xf86SetOperatingState(vgaio, pMga->pEnt->index, ResUnusedOpr); 	xf86SetOperatingState(vga1mem, pMga->pEnt->index, ResDisableOpr); 	xf86SetOperatingState(vga2mem, pMga->pEnt->index, ResDisableOpr);    }#else    /*     * Set our own access functions, which control the vgaioen bit.     */    pMga->Access.AccessDisable = VgaIODisable;    pMga->Access.AccessEnable = VgaIOEnable;    pMga->Access.arg = pMga;    /* please check if this is correct. I've impiled that the VGA fb       is handled locally and not visible outside. If the VGA fb is       handeled by the same function the third argument has to be set,       too.*/    xf86SetAccessFuncs(pMga->pEnt, &pMga->Access, &pMga->Access,			&pMga->Access, NULL);#endif    /* Set pScrn->monitor */    pScrn->monitor = pScrn->confScreen->monitor;    /*     * In case of DualHead, we need to determine if we are the 'master' head or the 'slave'     * head. In order to do that, at the end of the first initialisation, PrimInit is set as     * DONE to the shared entity. So that the second initialisation knows that something has     * been done before it. This always assume that the first device initialised is the master     * head, and the second the slave.     *      */    if (xf86IsEntityShared(pScrn->entityList[0])) {      /* dual-head mode */                if (!xf86IsPrimInitDone(pScrn->entityList[0])) { /* Is it the first initialisation? */            /* First CRTC  */            pMga->SecondCrtc = FALSE;            pMga->HWCursor = TRUE;            pMgaEnt->pScrn_1 = pScrn;        }        else {            /* Second CRTC */            pMga->SecondCrtc = TRUE;            pMga->HWCursor = FALSE;            pMgaEnt->pScrn_2 = pScrn;            pScrn->AdjustFrame = MGAAdjustFrameCrtc2;        }#ifdef XF86DRI        pMga->GetQuiescence = MGAGetQuiescenceShared;#endif    } else {                                              /* single-head mode */        pMga->SecondCrtc = FALSE;        pMga->HWCursor = TRUE;#ifdef XF86DRI        pMga->GetQuiescence = MGAGetQuiescence;#endif    }    /*     * The first thing we should figure out is the depth, bpp, etc.     * Our default depth is 8, so pass it to the helper function.     * We support both 24bpp and 32bpp layouts, so indicate that.     */    /* Prefer 24bpp fb unless the Overlay option is set, or DRI is     * supported.     */    flags24 = Support24bppFb | Support32bppFb | SupportConvert32to24;    s = xf86TokenToOptName(MGAOptions, OPTION_OVERLAY);#ifndef XF86DRI    if (!(xf86FindOption(pScrn->confScreen->options, s) ||	  xf86FindOption(pMga->device->options, s))) {	flags24 |= PreferConvert32to24;    }#endif    if (pMga->SecondCrtc)	flags24 = Support32bppFb;    if (!xf86SetDepthBpp(pScrn, 8, 8, 8, flags24)) {	return FALSE;    } else {	/* Check that the returned depth is one we support */	switch (pScrn->depth) {	case 8:	case 15:	case 16:	case 24:	    /* OK */	    break;	default:	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,		       "Given depth (%d) is not supported by this driver\n",		       pScrn->depth);	    return FALSE;	}    }    xf86PrintDepthBpp(pScrn);    /*     * This must happen after pScrn->display has been set because     * xf86SetWeight references it.     */    if (pScrn->depth > 8) {	/* The defaults are OK for us */	rgb zeros = {0, 0, 0};	if (!xf86SetWeight(pScrn, zeros, zeros)) {	    return FALSE;	} else {	    /* XXX check that weight returned is supported */            ;        }    }    bytesPerPixel = pScrn->bitsPerPixel / 8;    /* We use a programmable clock */    pScrn->progClock = TRUE;    /* Collect all of the relevant option flags (fill in pScrn->options) */    xf86CollectOptions(pScrn, NULL);    /* Process the options */    if (!(pMga->Options = xalloc(sizeof(MGAOptions))))	return FALSE;    memcpy(pMga->Options, MGAOptions, sizeof(MGAOptions));    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pMga->Options);#if !defined(__powerpc__)    pMga->softbooted = FALSE;    if (xf86ReturnOptValBool(pMga->Options, OPTION_INT10, FALSE) &&        xf86LoadSubModule(pScrn, "int10")) {        xf86Int10InfoPtr pInt;	xf86LoaderReqSymLists(int10Symbols, NULL);        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n");        pInt = xf86InitInt10(pMga->pEnt->index);	if (pInt) pMga->softbooted = TRUE;        xf86FreeInt10(pInt);    }#endif    /* Set the bits per RGB for 8bpp mode */    if (pScrn->depth == 8)	pScrn->rgbBits = 8;    /*     * Set the Chipset and ChipRev, allowing config file entries to     * override.     */    if (pMga->device->chipset && *pMga->device->chipset) {	pScrn->chipset = pMga->device->chipset;        pMga->Chipset = xf86StringToToken(MGAChipsets, pScrn->chipset);        from = X_CONFIG;    } else if (pMga->device->chipID >= 0) {	pMga->Chipset = pMga->device->chipID;	pScrn->chipset = (char *)xf86TokenToString(MGAChipsets, pMga->Chipset);	from = X_CONFIG;	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",		   pMga->Chipset);    } else {	from = X_PROBED;	pMga->Chipset = pMga->PciInfo->chipType;	pScrn->chipset = (char *)xf86TokenToString(MGAChipsets, pMga->Chipset);    }    if (pMga->device->chipRev >= 0) {	pMga->ChipRev = pMga->device->chipRev;	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",		   pMga->ChipRev);    } else {	pMga->ChipRev = pMga->PciInfo->chipRev;    }#ifdef USEMGAHAL    if (HAL_CHIPSETS) {        if (!xf86ReturnOptValBool(pMga->Options, OPTION_NOHAL, FALSE)	    && xf86LoadSubModule(pScrn, "mga_hal")) {	  xf86LoaderReqSymLists(halSymbols, NULL);	  xf86DrvMsg(pScrn->scrnIndex, X_INFO,"Matrox HAL module used\n");	  pMga->HALLoaded = TRUE;	} else {	  xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Matrox HAL module not loaded "		     "- using builtin mode setup instead\n");	  pMga->HALLoaded = FALSE;	}    }#endif    /*     * This shouldn't happen because such problems should be caught in     * MGAProbe(), but check it just in case.     */    if (pScrn->chipset == NULL) {	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,		   "ChipID 0x%04X is not recognised\n", pMga->Chipset);	return FALSE;    }    if (pMga->Chipset < 0) {	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,		   "Chipset \"%s\" is not recognised\n", pScrn->chipset);	return FALSE;    }    xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);#ifdef XF86DRI    from = X_DEFAULT;    pMga->agpMode = MGA_DEFAULT_AGP_MODE;    if (xf86GetOptValInteger(pMga->Options,			     OPTION_AGP_MODE, &(pMga->agpMode))) {       if (pMga->agpMode < 1) {	  pMga->agpMode = 1;       }       if (pMga->agpMode > MGA_MAX_AGP_MODE) {	  pMga->agpMode = MGA_MAX_AGP_MODE;       }       from = X_CONFIG;    }    xf86DrvMsg(pScrn->scrnIndex, from, "Using AGP %dx mode\n",	       pMga->agpMode);#endif    from = X_DEFAULT;    /*     * The preferred method is to use the "hw cursor" option as a tri-state     * option, with the default set above.     */    if (xf86GetOptValBool(pMga->Options, OPTION_HW_CURSOR, &pMga->HWCursor)) {	from = X_CONFIG;    }    /* For compatibility, accept this too (as an override) */    if (xf86ReturnOptValBool(pMga->Options, OPTION_NOACCEL, FALSE)) {	pMga->NoAccel = TRUE;	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");    }    if (xf86ReturnOptValBool(pMga->Options, OPTION_PCI_RETRY, FALSE)) {	pMga->UsePCIRetry = TRUE;	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");    }    if (xf86ReturnOptValBool(pMga->Options, OPTION_SYNC_ON_GREEN, FALSE)) {	pMga->SyncOnGreen = TRUE;	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Sync-on-Green enabled\n");    }    if (xf86ReturnOptValBool(pMga->Options, OPTION_SHOWCACHE, FALSE)) {	pMga->ShowCache = TRUE;	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShowCache enabled\n");    }    if (xf86ReturnOptValBool(pMga->Options, OPTION_MGA_SDRAM, FALSE)) {	pMga->HasSDRAM = TRUE;	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Has SDRAM\n");    }    if (xf86GetOptValFreq(pMga->Options, OPTION_SET_MCLK, OPTUNITS_MHZ, &real)) {	pMga->MemClk = (int)(real * 1000.0);    }    if ((s = xf86GetOptValString(pMga->Options, OPTION_OVERLAY))) {      if (!*s || !xf86NameCmp(s, "8,24") || !xf86NameCmp(s, "24,8")) {	if(pScrn->bitsPerPixel == 32 && pMga->SecondCrtc == FALSE) {	    pMga->Overlay8Plus24 = TRUE;	    if(!xf86GetOptValInteger(			pMga->Options, OPTION_COLOR_KEY,&(pMga->colorKey)))		pMga->colorKey = TRANSPARENCY_KEY;	    pScrn->colorKey = pMga->colorKey;	    pScrn->overlayFlags = OVERLAY_8_32_PLANAR;	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,				"PseudoColor overlay enabled\n");	} else {	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,	         "Option \"Overlay\" is only supported in 32 bits per pixel on"		 "the first CRTC\n");	}      } else {	  xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,		"\"%s\" is not a valid value for Option \"Overlay\"\n", s);      }    }    if(xf86GetOptValInteger(pMga->Options, OPTION_VIDEO_KEY, &(pMga->videoKey))) {	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n",				pMga->videoKey);    } else {	pMga->videoKey =  (1 << pScrn->offset.red) |			  (1 << pScrn->offset.green) |        (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << pScrn->offset.blue);    }    if (xf86ReturnOptValBool(pMga->Options, OPTION_SHADOW_FB, FALSE)) {	pMga->ShadowFB = TRUE;	pMga->NoAccel = TRUE;	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,		"Using \"Shadow Framebuffer\" - acceleration disabled\n");    }    if (xf86ReturnOptValBool(pMga->Options, OPTION_FBDEV, FALSE)) {	pMga->FBDev = TRUE;	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,		"Using framebuffer device\n");    }    if (xf86ReturnOptValBool(pMga->Options, OPTION_OVERCLOCK_MEM, FALSE)) {	pMga->OverclockMem = TRUE;	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Overclocking memory\n");    }    if (xf86ReturnOptValBool(pMga->Options, OPTION_TEXTURED_VIDEO, FALSE)) {	pMga->TexturedVideo = TRUE;    }    if (pMga->FBDev) {	/* check for linux framebuffer device */	if (!xf86LoadSubModule(pScrn, "fbdevhw"))	    return FALSE;	xf86LoaderReqSymLists(fbdevHWSymbols, NULL);	if (!fbdevHWInit(pScrn, pMga->PciInfo, NULL))	    return FALSE;	pScrn->SwitchMode    = fbdevHWSwitchMode;	pScrn->AdjustFrame   = fbdevHWAdjustFrame;	pScrn->EnterVT       = MGAEnterVTFBDev;	pScrn->LeaveVT       = fbdevHWLeaveVT;	pScrn->ValidMode     = fbdevHWValidMode;    }    pMga->Rotate = 0;    if ((s = xf86GetOptValString(pMga->Options, OPTION_ROTATE))) {      if(!xf86NameCmp(s, "CW")) {	pMga->ShadowFB = TRUE;	pMga->NoAccel = TRUE;	pMga->HWCursor = FALSE;	pMga->Rotate = 1;	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,		"Rotating screen clockwise - acceleration disabled\n");      } else      if(!xf86NameCmp(s, "CCW")) {	pMga->ShadowFB = TRUE;	pMga->NoAccel = TRUE;	pMga->HWCursor = FALSE;	pMga->Rotate = -1;	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,		"Rotating screen counter clockwise - acceleration disabled\n");      } else {	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,		"\"%s\" is not a valid value for Option \"Rotate\"\n", s);	xf86DrvMsg(pScrn->scrnIndex, X_INFO,		"Valid options are \"CW\" or \"CCW\"\n");      }    }    switch (pMga->Chipset) {    case PCI_CHIP_MGA2064:    case PCI_CHIP_MGA2164:    case PCI_CHIP_MGA2164_AGP:	MGA2064SetupFuncs(pScrn);	break;    case PCI_CHIP_MGA1064:    case PCI_CHIP_MGAG100:    case PCI_CHIP_MGAG100_PCI:    case PCI_CHIP_MGAG200:    case PCI_CHIP_MGAG200_PCI:    case PCI_CHIP_MGAG400:    case PCI_CHIP_MGAG550:	MGAGSetupFuncs(pScrn);	break;    }    /* ajv changes to reflect actual values. see sdk pp 3-2. */    /* these masks just get rid of the crap in the lower bits */    /*     * For the 2064 and older rev 1064, base0 is the MMIO and base0 is     * the framebuffer is base1.  Let the config file override these.     */    if (pMga->device->MemBase != 0) {	/* Require that the config file value matches one of the PCI values. */	if (!xf86CheckPciMemBase(pMga->PciInfo, pMga->device->MemBase)) {	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,		"MemBase 0x%08lX doesn't match any PCI base register.\n",		pMga->device->MemBase);	    MGAFreeRec(pScrn);	    return FALSE;	}	pMga->FbAddress = pMga->device->MemBase;	from = X_CONFIG;    } else {	/* details: mgabase2 sdk pp 4-12 */	int i = ((pMga->Chipset == PCI_CHIP_MGA1064 && pMga->ChipRev < 3) ||		    pMga->Chipset == PCI_CHIP_MGA2064) ? 1 : 0;	pMga->FbBaseReg = i;	if (pMga->PciInfo->memBase[i] != 0) {	    pMga->FbAddress = pMga->PciInfo->memBase[i] & 0xff800000;	    from = X_PROBED;	} else {	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,			   "No valid FB address in PCI config space\n");	    MGAFreeRec(pScrn);	    return FALSE;	}    }    xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",	       (unsigned long)pMga->FbAddress);#if !defined(__powerpc__)    if (pMga->device->IOBase != 0) {	/* Require that the config file value matches one of the PCI values. */	if (!xf86CheckPciMemBase(pMga->PciInfo, pMga->device->IOBase)) {	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,		"IOBase 0x%08lX doesn't match any PCI base register.\n",		pMga->device->IOBase);	    MGAFreeRec(pScrn);	    return FALSE;	}	pMga->IOAddress = pMga->device->IOBase;	from = X_CONFIG;    } else {	/* details: mgabase1 sdk pp 4-11 */	int i = ((pMga->Chipset == PCI_CHIP_MGA1064 && pMga->ChipRev < 3) ||		    pMga->Chipset == PCI_CHIP_MGA2064) ? 0 : 1;	if (pMga->PciInfo->memBase[i] != 0) {	    pMga->IOAddress = pMga->PciInfo->memBase[i] & 0xffffc000;	    from = X_PROBED;	} else {	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,			"No valid MMIO address in PCI config space\n");	    MGAFreeRec(pScrn);	    return FALSE;	}    }#else    pMga->IOAddress = pMga->PciInfo->memBase[0];#endif    xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",	       (unsigned long)pMga->IOAddress);    pMga->ILOADAddress = 0;    if ( pMga->Chipset != PCI_CHIP_MGA2064 ) {	    if (pMga->PciInfo->memBase[2] != 0) {	    	pMga->ILOADAddress = pMga->PciInfo->memBase[2] & 0xffffc000;	        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,			"Pseudo-DMA transfer window at 0x%lX\n",	       		(unsigned long)pMga->ILOADAddress);	    }    }#if !defined(__powerpc__)    /*     * Find the BIOS base.  Get it from the PCI config if possible.  Otherwise     * use the VGA default.  Allow the config file to override this.     */    pMga->BiosFrom = X_NONE;    if (pMga->device->BiosBase != 0) {	/* XXX This isn't used */	pMga->BiosAddress = pMga->device->BiosBase;	pMga->BiosFrom = X_CONFIG;    } else {	/* details: rombase sdk pp 4-15 */	if (pMga->PciInfo->biosBase != 0) {	    pMga->BiosAddress = pMga->PciInfo->biosBase & 0xffff0000;	    pMga->BiosFrom = X_PROBED;	} else if (pMga->Primary) {	    pMga->BiosAddress = 0xc0000;	    pMga->BiosFrom = X_DEFAULT;	}    }    if (pMga->BiosAddress) {	xf86DrvMsg(pScrn->scrnIndex, pMga->BiosFrom, "BIOS at 0x%lX\n",		   (unsigned long)pMga->BiosAddress);    }    if (xf86RegisterResources(pMga->pEnt->index, NULL, ResExclusive)) {	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,		"xf86RegisterResources() found resource conflicts\n");	MGAFreeRec(pScrn);	return FALSE;    }    /*     * Read the BIOS data struct     */#if defined(__alpha__)    /*      * Some old Digital-OEMed Matrox Millennium I cards have a VGA     * disable switch.  If the disable is on, we can't read the BIOS,     * and pMga->BiosAddress = 0x0. The disable switch is needed to     * allow multi-head operation with brain-dead console code... ;-}     */        if ((pMga->BiosAddress == 0) && !xf86IsPrimaryPci(pMga->PciInfo))        xf86DrvMsg(pScrn->scrnIndex, pMga->BiosFrom,                   "BIOS not found, skipping read\n");    else#endif    MGAReadBios(pScrn);    /* Since the BIOS can swap DACs during the initialisation of G550, we need to     * store which DAC this instance of the driver is taking care of. This is done     * by checking a flag stored in the ROM by the BIOS at a fixed address. */    if (!pMga->SecondCrtc)         pMga->SecondOutput = FALSE;    else        pMga->SecondOutput = TRUE;    if (pMga->Chipset == PCI_CHIP_MGAG550) {        if (!pMga->SecondCrtc) {            pMga->SecondOutput = (pMga->BiosOutputMode & 0x1) ? TRUE : FALSE;        } else {            pMga->SecondOutput = (pMga->BiosOutputMode & 0x1) ? FALSE : TRUE;        }    }    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2,		   "MGABios.RamdacType = 0x%x\n", pMga->Bios.RamdacType);#endif /* !__powerpc__ */    /* HW bpp matches reported bpp */    pMga->HwBpp = pScrn->bitsPerPixel;    /*     * Reset card if it isn't primary one     */    if ( (!pMga->Primary && !pMga->FBDev) || xf86IsPc98() )        MGASoftReset(pScrn);    /*     * If the user has specified the amount of memory in the XF86Config     * file, we respect that setting.     */    from = X_PROBED;    if (pMga->device->videoRam != 0) {	pScrn->videoRam = pMga->device->videoRam;	from = X_CONFIG;    } else if (pMga->FBDev) {	pScrn->videoRam = fbdevHWGetVidmem(pScrn)/1024;    } else {	pScrn->videoRam = MGACountRam(pScrn);    }    if(xf86IsEntityShared(pScrn->entityList[0])) {       /* This takes gives either half or 8 meg to the second head	* whichever is less. */        if(pMga->SecondCrtc == FALSE) {	    Bool UseHalf = FALSE;	    int adjust;	    xf86GetOptValBool(pMga->Options, OPTION_CRTC2HALF, &UseHalf);	    adjust = pScrn->videoRam / 2;	    if (UseHalf == TRUE ||		  xf86GetOptValInteger(pMga->Options, OPTION_CRTC2RAM, &adjust)) {	        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,			   "Crtc2 will use %dK of VideoRam\n",			   adjust);	    } else {	        adjust = min(adjust, 8192);	        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,			   "Crtc2 will use %dK of VideoRam\n",			   adjust);	    }	    pMgaEnt->mastervideoRam = pScrn->videoRam - adjust;	    pScrn->videoRam = pMgaEnt->mastervideoRam;	    pMgaEnt->slavevideoRam = adjust;	    pMgaEnt->masterFbAddress = pMga->FbAddress;	    pMga->FbMapSize =	       pMgaEnt->masterFbMapSize = pScrn->videoRam * 1024;	    pMgaEnt->slaveFbAddress = pMga->FbAddress +	       pMgaEnt->masterFbMapSize;	    pMgaEnt->slaveFbMapSize = pMgaEnt->slavevideoRam * 1024;	    pMga->realSrcOrg = pMga->SrcOrg = 0;	    pMga->DstOrg = 0;	} else {	    pMga->FbAddress = pMgaEnt->slaveFbAddress;	    pMga->FbMapSize = pMgaEnt->slaveFbMapSize;	    pScrn->videoRam = pMgaEnt->slavevideoRam;	    pMga->DstOrg = pMga->realSrcOrg =	      pMgaEnt->slaveFbAddress - pMgaEnt->masterFbAddress;	    pMga->SrcOrg = 0; /* This is not stored in hw format!! */	}        pMgaEnt->refCount++;    } else {        /* Normal Handling of video ram etc */        pMga->FbMapSize = pScrn->videoRam * 1024;        switch(pMga->Chipset) {	  case PCI_CHIP_MGAG550:	  case PCI_CHIP_MGAG400:	  case PCI_CHIP_MGAG200:	  case PCI_CHIP_MGAG200_PCI:	    pMga->SrcOrg = 0;	    pMga->DstOrg = 0;	    break;	  default:	    break;	}    }    xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",               pScrn->videoRam);   /* Set the bpp shift value */    pMga->BppShifts[0] = 0;    pMga->BppShifts[1] = 1;    pMga->BppShifts[2] = 0;    pMga->BppShifts[3] = 2;    /*     * fill MGAdac struct     * Warning: currently, it should be after RAM counting     */    (*pMga->PreInit)(pScrn);#if !defined(__powerpc__)    /* Read and print the Monitor DDC info */    pScrn->monitor->DDC = MGAdoDDC(pScrn);#endif /* !__powerpc__ */    /*     * If the driver can do gamma correction, it should call xf86SetGamma()     * here.     */    {	Gamma zeros = {0.0, 0.0, 0.0};	if (!xf86SetGamma(pScrn, zeros)) {	    return FALSE;	}    }    /* XXX Set HW cursor use */    /* Set the min pixel clock */    pMga->MinClock = 12000;	/* XXX Guess, need to check this */    xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",	       pMga->MinClock / 1000);    /*     * If the user has specified ramdac speed in the XF86Config     * file, we respect that setting.     */    if (pMga->device->dacSpeeds[0]) {	int speed = 0;	switch (pScrn->bitsPerPixel) {	case 8:	   speed = pMga->device->dacSpeeds[DAC_BPP8];	   break;	case 16:	   speed = pMga->device->dacSpeeds[DAC_BPP16];	   break;	case 24:	   speed = pMga->device->dacSpeeds[DAC_BPP24];	   break;	case 32:	   speed = pMga->device->dacSpeeds[DAC_BPP32];	   break;	}	if (speed == 0)	    pMga->MaxClock = pMga->device->dacSpeeds[0];	else	    pMga->MaxClock = speed;	from = X_CONFIG;    } else {	pMga->MaxClock = pMga->Dac.maxPixelClock;	from = pMga->Dac.ClockFrom;    }    if(pMga->SecondCrtc == TRUE) {        /* Override on 2nd crtc */	if ((pMga->ChipRev >= 0x80) || (pMga->Chipset == PCI_CHIP_MGAG550)) {	    /* G450, G550 */	    pMga->MaxClock = 234000;	} else {	    pMga->MaxClock = 135000;	}    }    xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",	       pMga->MaxClock / 1000);    /*     * Setup the ClockRanges, which describe what clock ranges are available,     * and what sort of modes they can be used for.     */    clockRanges = xnfcalloc(sizeof(ClockRange), 1);    clockRanges->next = NULL;    clockRanges->minClock = pMga->MinClock;    clockRanges->maxClock = pMga->MaxClock;    clockRanges->clockIndex = -1;		/* programmable */    clockRanges->interlaceAllowed = TRUE;    clockRanges->doubleScanAllowed = TRUE;#ifdef USEMGAHAL    MGA_HAL(clockRanges->interlaceAllowed = FALSE);    MGA_HAL(clockRanges->doubleScanAllowed = FALSE);#endif    if (pMga->SecondCrtc == TRUE)	clockRanges->interlaceAllowed = FALSE;    clockRanges->ClockMulFactor = 1;    clockRanges->ClockDivFactor = 1;    /* Only set MemClk if appropriate for the ramdac */    if (pMga->Dac.SetMemClk) {	if (pMga->MemClk == 0) {	    pMga->MemClk = pMga->Dac.MemoryClock;	    from = pMga->Dac.MemClkFrom;	} else	    from = X_CONFIG;	xf86DrvMsg(pScrn->scrnIndex, from, "MCLK used is %.1f MHz\n",		   pMga->MemClk / 1000.0);    }    /*     * xf86ValidateModes will check that the mode HTotal and VTotal values     * don't exceed the chipset's limit if pScrn->maxHValue and     * pScrn->maxVValue are set.  Since our MGAValidMode() already takes     * care of this, we don't worry about setting them here.     */    {	int Pitches1[] =	  {640, 768, 800, 960, 1024, 1152, 1280, 1600, 1920, 2048, 0};	int Pitches2[] =	  {512, 640, 768, 800, 832, 960, 1024, 1152, 1280, 1600, 1664,		1920, 2048, 0};	int *linePitches = NULL;	int minPitch = 256;	int maxPitch = 2048;        switch(pMga->Chipset) {	case PCI_CHIP_MGA2064:	   if (!pMga->NoAccel) {		linePitches = xalloc(sizeof(Pitches1));		memcpy(linePitches, Pitches1, sizeof(Pitches1));		minPitch = maxPitch = 0;	   }	   break;	case PCI_CHIP_MGA2164:	case PCI_CHIP_MGA2164_AGP:	case PCI_CHIP_MGA1064:	   if (!pMga->NoAccel) {		linePitches = xalloc(sizeof(Pitches2));		memcpy(linePitches, Pitches2, sizeof(Pitches2));		minPitch = maxPitch = 0;	   }	   break;	case PCI_CHIP_MGAG100:	case PCI_CHIP_MGAG100_PCI:	   maxPitch = 2048;	   break;	case PCI_CHIP_MGAG200:	case PCI_CHIP_MGAG200_PCI:	case PCI_CHIP_MGAG400:	case PCI_CHIP_MGAG550:	   maxPitch = 4096;	   break;	}	i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,			      pScrn->display->modes, clockRanges,			      linePitches, minPitch, maxPitch,			      pMga->Roundings[(pScrn->bitsPerPixel >> 3) - 1] *					pScrn->bitsPerPixel, 128, 2048,			      pScrn->display->virtualX,			      pScrn->display->virtualY,			      pMga->FbMapSize,			      LOOKUP_BEST_REFRESH);	if (linePitches)	   xfree(linePitches);    }    if (i < 1 && pMga->FBDev) {	fbdevHWUseBuildinMode(pScrn);	pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */	i = 1;    }    if (i == -1) {	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Validate Modes Failed\n");	MGAFreeRec(pScrn);	return FALSE;    }    /* Prune the modes marked as invalid */    xf86PruneDriverModes(pScrn);    if (i == 0 || pScrn->modes == NULL) {	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");	MGAFreeRec(pScrn);	return FALSE;    }#ifdef USEMGAHAL    MGA_HAL(    swap_head        = xf86ReturnOptValBool(pMga->Options, OPTION_SWAPPED_HEAD, FALSE);    if(pMga->SecondCrtc == FALSE) {        pMga->pBoard = xalloc(sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize());        pMga->pClientStruct = xalloc(sizeof(CLIENTDATA));        pMga->pClientStruct->pMga = (MGAPtr) pMga;        MGAMapMem(pScrn);        MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA));        MGAUnmapMem(pScrn);        pMga->pMgaHwInfo = xalloc(sizeof(MGAHWINFO));        MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo);        digital1 = ISDIGITAL1(pMga);        digital2 = ISDIGITAL2(pMga);        tv1 = ISTV1(pMga);        tv2 = ISTV2(pMga);        /* Display type information */        if (digital1) {            xf86DrvMsg(pScrn->scrnIndex, X_INFO,				"Digital screen detected on first head.\n");            mgaModeInfo.flOutput = MGAMODEINFO_DIGITAL1;        } else if (tv1) {            xf86DrvMsg(pScrn->scrnIndex, X_INFO,				"TV detected on first head.\n");            mgaModeInfo.flOutput = MGAMODEINFO_TV;        } else {            if (!swap_head) {                mgaModeInfo.flOutput = MGAMODEINFO_ANALOG1;            } else {                mgaModeInfo.flOutput = MGAMODEINFO_ANALOG2;            }        }        /* copy the board handles */        if (xf86IsEntityShared(pScrn->entityList[0])) {            pMgaEnt->pClientStruct = pMga->pClientStruct;            pMgaEnt->pBoard = pMga->pBoard;            pMgaEnt->pMgaHwInfo = pMga->pMgaHwInfo;        }        mgaModeInfo.ulDispWidth = pScrn->virtualX;        mgaModeInfo.ulDispHeight = pScrn->virtualY;        mgaModeInfo.ulDeskWidth = pScrn->virtualX;        mgaModeInfo.ulDeskHeight = pScrn->virtualY;        mgaModeInfo.ulBpp = pScrn->bitsPerPixel;        mgaModeInfo.ulZoom = 1;    } else { /* Second CRTC && entity is shared */        if (digital2 == TRUE) {            mgaModeInfo.flOutput = MGAMODEINFO_DIGITAL2 |            			   MGAMODEINFO_SECOND_CRTC;        } else if (tv2 == TRUE) {            mgaModeInfo.flOutput = MGAMODEINFO_TV |            			   MGAMODEINFO_SECOND_CRTC;        } else {            if (!swap_head) {              mgaModeInfo.flOutput = MGAMODEINFO_ANALOG2 |            			     MGAMODEINFO_SECOND_CRTC;            } else {	      mgaModeInfo.flOutput = MGAMODEINFO_ANALOG1 |                                     MGAMODEINFO_SECOND_CRTC;            }        }        mgaModeInfo.ulDispWidth = pScrn->virtualX;        mgaModeInfo.ulDispHeight = pScrn->virtualY;        mgaModeInfo.ulDeskWidth = pScrn->virtualX;        mgaModeInfo.ulDeskHeight = pScrn->virtualY;        mgaModeInfo.ulBpp = pScrn->bitsPerPixel;        mgaModeInfo.ulZoom = 1;        pMga->pBoard = pMgaEnt->pBoard;        pMga->pClientStruct = pMgaEnt->pClientStruct;        pMga->pMgaHwInfo = pMgaEnt->pMgaHwInfo;        digital1 = ISDIGITAL1(pMga);        digital2 = ISDIGITAL2(pMga);        tv1 = ISTV1(pMga);        tv2 = ISTV2(pMga);                          if (digital2) {            xf86DrvMsg(pScrn->scrnIndex, X_INFO,			"Digital screen detected on second head.\n");            mgaModeInfo.flOutput = MGAMODEINFO_DIGITAL2 |				   MGAMODEINFO_SECOND_CRTC;         } else if (tv2) {            xf86DrvMsg(pScrn->scrnIndex, X_INFO,			"TV detected on second head.\n");            mgaModeInfo.flOutput = MGAMODEINFO_TV |				   MGAMODEINFO_SECOND_CRTC;        } else {            mgaModeInfo.flOutput = MGAMODEINFO_ANALOG2 |				   MGAMODEINFO_SECOND_CRTC;        }    }    if((status = MGAValidateMode(pMga->pBoard,&mgaModeInfo)) != 0) {	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,		   "MGAValidateMode from HALlib found the mode to be invalid.\n"		   "\tError: 0x%lx\n", status);        return FALSE;    }    pScrn->displayWidth = mgaModeInfo.ulFBPitch;    );	/* MGA_HAL */#endif    if (pMga->HasSDRAM) { /* don't bother checking */ }    else if ((pMga->PciInfo->subsysCard == PCI_CARD_MILL_G200_SD) ||	(pMga->PciInfo->subsysCard == PCI_CARD_MARV_G200_SD) ||	(pMga->PciInfo->subsysCard == PCI_CARD_MYST_G200_SD) ||	(pMga->PciInfo->subsysCard == PCI_CARD_PROD_G100_SD)) {        pMga->HasSDRAM = TRUE;	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Has SDRAM\n");    }    /*     * Can we trust HALlib to set the memory configuration     * registers correctly?     */    else if ((pMga->softbooted || pMga->Primary /*|| pMga->HALLoaded*/ ) &&	     (pMga->Chipset != PCI_CHIP_MGA2064) &&	     (pMga->Chipset != PCI_CHIP_MGA2164) &&	     (pMga->Chipset != PCI_CHIP_MGA2164_AGP)) {        CARD32 option_reg = pciReadLong(pMga->PciTag, PCI_OPTION_REG);	if(!(option_reg & (1 << 14))) {	    pMga->HasSDRAM = TRUE;	    xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Has SDRAM\n");	}    }    /*     * Set the CRTC parameters for all of the modes based on the type     * of mode, and the chipset's interlace requirements.     *     * Calling this is required if the mode->Crtc* values are used by the     * driver and if the driver doesn't provide code to set them.  They     * are not pre-initialised at all.     */#ifdef USEMGAHAL    MGA_HAL(xf86SetCrtcForModes(pScrn, 0));#endif    MGA_NOT_HAL(xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V));    /* Set the current mode to the first in the list */    pScrn->currentMode = pScrn->modes;    /* Print the list of modes being used */    xf86PrintModes(pScrn);    /* Set display resolution */    xf86SetDpi(pScrn, 0, 0);    /*     * Compute the byte offset into the linear frame buffer where the     * frame buffer data should actually begin.  According to DDK misc.c     * line 1023, if more than 4MB is to be displayed, YDSTORG must be set     * appropriately to align memory bank switching, and this requires a     * corresponding offset on linear frame buffer access.     * This is only needed for WRAM.     */    pMga->YDstOrg = 0;    if (((pMga->Chipset == PCI_CHIP_MGA2064) ||	 (pMga->Chipset == PCI_CHIP_MGA2164) ||	 (pMga->Chipset == PCI_CHIP_MGA2164_AGP)) &&	(pScrn->virtualX * pScrn->virtualY * bytesPerPixel > 4*1024*1024))    {	int offset, offset_modulo, ydstorg_modulo;	offset = (4*1024*1024) % (pScrn->displayWidth * bytesPerPixel);	offset_modulo = 4;	ydstorg_modulo = 64;	if (pScrn->bitsPerPixel == 24)	    offset_modulo *= 3;	if (pMga->Interleave)	{	    offset_modulo <<= 1;	    ydstorg_modulo <<= 1;	}	pMga->YDstOrg = offset / bytesPerPixel;	/*	 * When this was unconditional, it caused a line of horizontal garbage	 * at the middle right of the screen at the 4Meg boundary in 32bpp	 * (and presumably any other modes that use more than 4M). But it's	 * essential for 24bpp (it may not matter either way for 8bpp & 16bpp,	 * I'm not sure; I didn't notice problems when I checked with and	 * without.)	 * DRM Doug Merritt 12/97, submitted to XFree86 6/98 (oops)	 */	if (bytesPerPixel < 4) {	    while ((offset % offset_modulo) != 0 ||		   (pMga->YDstOrg % ydstorg_modulo) != 0) {		offset++;		pMga->YDstOrg = offset / bytesPerPixel;	    }	}    }    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "YDstOrg is set to %d\n",		   pMga->YDstOrg);    if(xf86IsEntityShared(pScrn->entityList[0])) {        if(pMga->SecondCrtc == FALSE) {	    pMga->FbUsableSize = pMgaEnt->masterFbMapSize;            /* Allocate HW cursor buffer at the end of video ram */	    if( pMga->HWCursor && pMga->Dac.CursorOffscreenMemSize ) {	        if( pScrn->virtualY * pScrn->displayWidth *		    pScrn->bitsPerPixel / 8 <=		    pMga->FbUsableSize - pMga->Dac.CursorOffscreenMemSize ) {		    pMga->FbUsableSize -= pMga->Dac.CursorOffscreenMemSize;		    pMga->FbCursorOffset =		      pMgaEnt->masterFbMapSize -		      pMga->Dac.CursorOffscreenMemSize;		} else {		    pMga->HWCursor = FALSE;		    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,			       "Too little offscreen memory for HW cursor; "			       "using SW cursor\n");		}	    }	} else { /* Second CRTC */	    pMga->FbUsableSize = pMgaEnt->slaveFbMapSize;	    pMga->HWCursor = FALSE;	}    } else {        pMga->FbUsableSize = pMga->FbMapSize - pMga->YDstOrg * bytesPerPixel;           /* Allocate HW cursor buffer at the end of video ram */        if( pMga->HWCursor && pMga->Dac.CursorOffscreenMemSize ) {	    if( pScrn->virtualY * pScrn->displayWidth *	        pScrn->bitsPerPixel / 8 <=        	pMga->FbUsableSize - pMga->Dac.CursorOffscreenMemSize ) {	        pMga->FbUsableSize -= pMga->Dac.CursorOffscreenMemSize;	        pMga->FbCursorOffset =		  pMga->FbMapSize - pMga->Dac.CursorOffscreenMemSize;	    } else {	        pMga->HWCursor = FALSE;	        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,			   "Too little offscreen memory for HW cursor; "			   "using SW cursor\n");	    }	}    }    /*     * XXX This should be taken into account in some way in the mode valdation     * section.     */    /* Load the required framebuffer */    if (pMga->Overlay8Plus24) {	if (!xf86LoadSubModule(pScrn, "xf8_32bpp")) {	    MGAFreeRec(pScrn);	    return FALSE;	}	xf86LoaderReqSymLists(xf8_32bppSymbols, NULL);    } else {	if (!xf86LoadSubModule(pScrn, "fb")) {	    MGAFreeRec(pScrn);	    return FALSE;	}	xf86LoaderReqSymLists(fbSymbols, NULL);    }    /* Load XAA if needed */    if (!pMga->NoAccel) {	if (!xf86LoadSubModule(pScrn, "xaa")) {	    MGAFreeRec(pScrn);	    return FALSE;	}	xf86LoaderReqSymLists(xaaSymbols, NULL);    }    /* Load ramdac if needed */    if (pMga->HWCursor) {	if (!xf86LoadSubModule(pScrn, "ramdac")) {	    MGAFreeRec(pScrn);	    return FALSE;	}	xf86LoaderReqSymLists(ramdacSymbols, NULL);    }    /* Load shadowfb if needed */    if (pMga->ShadowFB) {	if (!xf86LoadSubModule(pScrn, "shadowfb")) {	    MGAFreeRec(pScrn);	    return FALSE;	}	xf86LoaderReqSymLists(shadowSymbols, NULL);    }    pMga->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;    pMga->CurrentLayout.depth = pScrn->depth;    pMga->CurrentLayout.displayWidth = pScrn->displayWidth;    pMga->CurrentLayout.weight.red = pScrn->weight.red;    pMga->CurrentLayout.weight.green = pScrn->weight.green;    pMga->CurrentLayout.weight.blue = pScrn->weight.blue;    pMga->CurrentLayout.Overlay8Plus24 = pMga->Overlay8Plus24;    pMga->CurrentLayout.mode = pScrn->currentMode;#ifdef USEMGAHAL    MGA_HAL(    /* Close the library after preinit */    /* This needs to only happen after this board has completed preinit     * both times     */      if(xf86IsEntityShared(pScrn->entityList[0])) {	  /* Entity is shared make sure refcount == 2 */	  /* If ref count is 2 then reset it to 0 */	  if(pMgaEnt->refCount == 2) {	      /* Both boards have done there initialization */	      MGACloseLibrary(pMga->pBoard);	      if (pMga->pBoard)	        xfree(pMga->pBoard);	      if (pMga->pClientStruct)	        xfree(pMga->pClientStruct);	      if (pMga->pMgaModeInfo)	        xfree(pMga->pMgaModeInfo);	      if (pMga->pMgaHwInfo)	        xfree(pMga->pMgaHwInfo);	      pMgaEnt->refCount = 0;	  }      } else {	  MGACloseLibrary(pMga->pBoard);	  if (pMga->pBoard)	    xfree(pMga->pBoard);	  if (pMga->pClientStruct)	    xfree(pMga->pClientStruct);	  if (pMga->pMgaModeInfo)	    xfree(pMga->pMgaModeInfo);	  if (pMga->pMgaHwInfo)	    xfree(pMga->pMgaHwInfo);      }    );	/* MGA_HAL */#endif    xf86SetPrimInitDone(pScrn->entityList[0]);    return TRUE;}