diff -ur xf86-video-mga-X11R7.2-1.4.6.1/src/mga_bios.c mga/src/mga_bios.c --- xf86-video-mga-X11R7.2-1.4.6.1/src/mga_bios.c 2007-01-08 18:45:22.000000000 -0500 +++ mga/src/mga_bios.c 2007-02-22 13:57:27.000000000 -0500 @@ -147,6 +147,14 @@ break; case PCI_CHIP_MGAG200_SE_A_PCI: + bios->system.max_freq = 230000; + bios->system.min_freq = 50000; + bios->pixel.max_freq = 230000; + bios->pll_ref_freq = 27050; + bios->mem_clock = 50000; + bios->host_interface = MGA_HOST_PCI; + break; + case PCI_CHIP_MGAG200_SE_B_PCI: bios->system.max_freq = 114000; bios->system.min_freq = 50000; diff -ur xf86-video-mga-X11R7.2-1.4.6.1/src/mga_driver.c mga/src/mga_driver.c --- xf86-video-mga-X11R7.2-1.4.6.1/src/mga_driver.c 2007-01-08 18:45:22.000000000 -0500 +++ mga/src/mga_driver.c 2007-02-22 15:37:36.000000000 -0500 @@ -737,6 +737,36 @@ MGAUnmapMem(pScrn); } +static CARD32 MGAGetVRefresh(ScrnInfoPtr pScrn) +{ + float hsync, refresh = 0; + + if (pScrn->modes->HSync > 0.0) + hsync = pScrn->modes->HSync; + else if (pScrn->modes->HTotal > 0) + hsync = (float)pScrn->modes->Clock / (float)pScrn->modes->HTotal; + else + hsync = 0.0; + + if (pScrn->modes->VTotal > 0) + refresh = hsync * 1000.0 / pScrn->modes->VTotal; + + if (pScrn->modes->Flags & V_INTERLACE) + refresh *= 2.0; + + if (pScrn->modes->Flags & V_DBLSCAN) + refresh /= 2.0; + + if (pScrn->modes->VScan > 1) + refresh /= pScrn->modes->VScan; + + /* assume 60Hz if we have nothing */ + if (refresh == 0.0) + refresh = 60.0; + + return (CARD32)refresh; +} + /* * MGACountRAM -- * @@ -747,8 +777,12 @@ { MGAPtr pMga = MGAPTR(pScrn); int ProbeSize = 8192; + int ProbeSizeOffset = 0x1000; int SizeFound = 2048; CARD32 biosInfo = 0; + CARD8 seq1; + CARD8 Temp; + #if 0 /* This isn't correct. It looks like this can have arbitrary @@ -787,6 +821,7 @@ case PCI_CHIP_MGAG200_SE_A_PCI: case PCI_CHIP_MGAG200_SE_B_PCI: ProbeSize = 4096; + ProbeSizeOffset = 0x800; break; case PCI_CHIP_MGAG200: case PCI_CHIP_MGAG200_PCI: @@ -835,13 +880,26 @@ CARD32 TestMemoryLoc0, TestMemoryLoc1; CARD32 TestA, TestB; + if (pMga->is_G200SE_A) { + CARD8 localtemp; + localtemp = INREG8(0x1E24); + if (localtemp == 0x01) { + MGAUnmapMem(pScrn); + ProbeSize = 16384; + ProbeSizeOffset = 0x10000; + pMga->FbMapSize = ProbeSize * 1024; + MGAMapMem(pScrn); + base = pMga->FbBase; + } + } + MemoryAt0 = base[0]; MemoryAt1 = base[1]; base[0] = 0; base[1] = 0; for (Offset = 0x100000; Offset < (ProbeSize * 1024); - Offset += 0x1000) { + Offset += ProbeSizeOffset) { FirstMemoryVal1 = base[Offset]; FirstMemoryVal2 = base[Offset+1]; SecondMemoryVal1 = base[Offset+0x100]; @@ -1142,6 +1214,8 @@ int flags24; MGAEntPtr pMgaEnt = NULL; Bool Default; + CARD32 temp; + CARD32 BW; #ifdef USEMGAHAL ULONG status; CARD8 MiscCtlReg; @@ -1425,6 +1500,25 @@ return FALSE; } } + + if (pMga->is_G200SE_A) { + pMga->FbAddress = pMga->PciInfo->memBase[0] & 0xff800000; + pMga->IOAddress = pMga->PciInfo->memBase[1] & 0xffffc000; + pMga->ILOADAddress = pMga->PciInfo->memBase[2] & 0xffffc000; + pScrn->videoRam = 8192; + pMga->FbMapSize = pScrn->videoRam * 1024; + MGAMapMem(pScrn); + if (INREG(0x1E24) == 0x1) { + if ((pScrn->bitsPerPixel == 24) && (pScrn->depth == 24)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given color and fb depth combination not supported by this driver\n", + pScrn->depth); + return FALSE; + } + } + MGAUnmapMem(pScrn); + } + xf86PrintDepthBpp(pScrn); /* @@ -2185,31 +2293,49 @@ pMga->pMgaModeInfo->ulDispWidth = pScrn->virtualX; pMga->pMgaModeInfo->ulDispHeight = pScrn->virtualY; - - if (ISDIGITAL1(pMga)) + if (ISDIGITAL1(pMga)) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Digital screen detected on first head.\n"); - if (ISTV1(pMga)) + if (ISTV1(pMga)) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV detected on first head.\n"); - if (ISDIGITAL2(pMga)) + if (ISDIGITAL2(pMga)) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Digital screen detected on second head.\n"); if (ISTV2(pMga)) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV detected on second head.\n"); - if((status = MGAValidateMode(pMga->pBoard,pMga->pMgaModeInfo)) != 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 = pMga->pMgaModeInfo->ulFBPitch; ); /* MGA_HAL */ #endif + if (pMga->is_G200SE_A) { + CARD32 VRefresh = MGAGetVRefresh(pScrn); + MGAMapMem(pScrn); + if (INREG(0x1e24) == 0x01) { + CARD32 BW = 0; + BW = pScrn->modes->VDisplay + * pScrn->modes->HDisplay + * VRefresh + * (pScrn->bitsPerPixel / 8); + if (BW > MAX_BW) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Mode [%dx%d] found to be invalid. [1]\n", + pScrn->modes->HDisplay, pScrn->modes->VDisplay ); + return FALSE; + } + } + MGAUnmapMem(pScrn); + } + 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) || @@ -2331,7 +2457,7 @@ pMga->FbUsableSize = pMgaEnt->slaveFbMapSize; pMga->HWCursor = FALSE; } - } else { + } else { pMga->FbUsableSize = pMga->FbMapSize - pMga->YDstOrg * bytesPerPixel; /* Allocate HW cursor buffer at the end of video ram */ if( pMga->HWCursor && pMga->Dac.CursorOffscreenMemSize ) { @@ -2426,14 +2552,14 @@ pMga->CurrentLayout.weight.blue = pScrn->weight.blue; pMga->CurrentLayout.Overlay8Plus24 = pMga->Overlay8Plus24; pMga->CurrentLayout.mode = pScrn->currentMode; - - + + if(pMga->MergedFB) { MGAPreInitMergedFB(pScrn,flags); }; - + #ifdef USEMGAHAL MGA_HAL( /* Close the library after preinit */ @@ -2817,25 +2947,41 @@ } } ); /*MGA_HAL */ - + #endif + if (pMga->is_G200SE_A) { + CARD32 VRefresh = MGAGetVRefresh(pScrn); + if (INREG(0x1e24) == 0x01) { + CARD32 BW = 0; + BW = mode->HDisplay + * mode->VDisplay + * VRefresh + * (pScrn->bitsPerPixel / 8); + if (BW > MAX_BW) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Mode [%dx%d] found to be invalid. [2]\n", mode->HDisplay, mode->VDisplay ); + return FALSE; + } + } + } + #ifdef USEMGAHAL MGA_HAL( /*************************** ESC *****************************/ TmpMgaModeInfo[0] = *pMga->pMgaModeInfo; - + if(pMga->SecondCrtc == TRUE) pMgaModeInfo[1] = pMga->pMgaModeInfo; else pMgaModeInfo[0] = pMga->pMgaModeInfo; - + TmpMgaModeInfo[0].ulDispWidth = 0; - - if(!pMga->MergedFB) /* FIXME: Must deal with this once PowerDesk & MergedFB + + if(!pMga->MergedFB) /* FIXME: Must deal with this once PowerDesk & MergedFB compatibility will exist */ - MGAFillDisplayModeStruct(mode, pMga->pMgaModeInfo); + MGAFillDisplayModeStruct(mode, pMga->pMgaModeInfo); /*************************************************************/ ); /* MGA_HAL */ @@ -2912,6 +3062,19 @@ outb(0xfac, 0x02); } + MGA_NOT_HAL( + if (pMga->is_G200SE) { + CARD8 value = 0x14; + if (pMga->is_G200SE_A) { + if (INREG(0x1E24) == 0x1) { + value = 0x03; + } + } + OUTREG8(0x1FDE, 0x06); + OUTREG8(0x1FDF, value); + } + ); + pMga->CurrentLayout.mode = mode; if(pMga->MergedFB && mode->Private && (mode->PrivSize == 0)) { @@ -3082,10 +3253,10 @@ if (pMga->is_G200SE) { VRTemp = pScrn->videoRam; FBTemp = pMga->FbMapSize; - pScrn->videoRam = 4096; + pScrn->videoRam = 8192; pMga->FbMapSize = pScrn->videoRam * 1024; } - + /* Map the MGA memory and MMIO areas */ if (pMga->FBDev) { if (!MGAMapMemFBDev(pScrn)) @@ -3953,7 +4124,7 @@ static void MGAFreeScreen(int scrnIndex, int flags) { - + /* * This only gets called when a screen is being deleted. It does not * get called routinely at the end of a server generation.