From 07373669514b104a11fb1b4ed5214f3764c83a2f Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Sun, 2 Apr 2006 01:03:50 +0000 Subject: Bug #6328: Add support for Matrox G200SE chips. (Matrox) --- src/Makefile.am | 1 + src/mga.h | 14 +++- src/mga_bios.c | 10 +++ src/mga_dacG.c | 120 ++++++++++++++++++++++++++---- src/mga_dga.c | 12 ++- src/mga_driver.c | 125 +++++++++++++++++++++++++++---- src/mga_macros.h | 2 + src/mga_merge.c | 4 + src/mga_storm.c | 20 ++++- src/mga_vga.c | 221 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 497 insertions(+), 32 deletions(-) create mode 100644 src/mga_vga.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 19ff915..0fa8d93 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -56,6 +56,7 @@ mga_drv_la_SOURCES = \ mga_shadow.c \ mga_storm.c \ mga_ucode.h \ + mga_vga.c \ mga_video.c if DRI diff --git a/src/mga.h b/src/mga.h index 7b4a209..d12d940 100644 --- a/src/mga.h +++ b/src/mga.h @@ -118,6 +118,14 @@ void MGAdbg_outreg32(ScrnInfoPtr, int,int, char*); #define OUTREG(addr,val) MGAdbg_outreg32(pScrn, addr, val, __FUNCTION__) #endif /* EXTRADEBUG */ +#ifndef PCI_CHIP_MGAG200_SE_A_PCI +#define PCI_CHIP_MGAG200_SE_A_PCI 0x0522 +#endif + +#ifndef PCI_CHIP_MGAG200_SE_B_PCI +#define PCI_CHIP_MGAG200_SE_B_PCI 0x0524 +#endif + /* * Read/write to the DAC via MMIO */ @@ -152,8 +160,8 @@ void MGAdbg_outreg32(ScrnInfoPtr, int,int, char*); #define MGA_MODULE_DATA mgaModuleData #define MGA_DRIVER_NAME "mga" #define MGA_MAJOR_VERSION 1 -#define MGA_MINOR_VERSION 2 -#define MGA_PATCHLEVEL 1 +#define MGA_MINOR_VERSION 3 +#define MGA_PATCHLEVEL 0 typedef struct { unsigned char ExtVga[6]; @@ -658,6 +666,8 @@ void MGAG450PrintPLL(ScrnInfoPtr pScrn); #endif long MGAG450SavePLLFreq(ScrnInfoPtr pScrn); void MGAprintDac(ScrnInfoPtr pScrn); +void MGAG200SESaveFonts(ScrnInfoPtr, vgaRegPtr); +void MGAG200SERestoreFonts(ScrnInfoPtr, vgaRegPtr); #ifdef USEMGAHAL /************ ESC Call Definition ***************/ diff --git a/src/mga_bios.c b/src/mga_bios.c index 957e3e4..282b558 100644 --- a/src/mga_bios.c +++ b/src/mga_bios.c @@ -147,6 +147,16 @@ static void mga_initialize_bios_values( MGAPtr pMga, bios->host_interface = MGA_HOST_PCI; break; + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: + bios->system.max_freq = 114000; + bios->system.min_freq = 50000; + bios->pixel.max_freq = 114000; + bios->pll_ref_freq = 27050; + bios->mem_clock = 45000; + bios->host_interface = MGA_HOST_PCI; + break; + case PCI_CHIP_MGAG100_PCI: case PCI_CHIP_MGAG100: case PCI_CHIP_MGAG200_PCI: diff --git a/src/mga_dacG.c b/src/mga_dacG.c index 728dd89..9d10811 100644 --- a/src/mga_dacG.c +++ b/src/mga_dacG.c @@ -60,6 +60,52 @@ static Bool MGAGInit(ScrnInfoPtr, DisplayModePtr); static void MGAGLoadPalette(ScrnInfoPtr, int, int*, LOCO*, VisualPtr); static Bool MGAG_i2cInit(ScrnInfoPtr pScrn); +static void +MGAG200SEComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P) +{ + unsigned int ulComputedFo; + unsigned int ulFDelta; + unsigned int ulFPermitedDelta; + unsigned int ulFTmpDelta; + unsigned int ulVCOMax, ulVCOMin; + unsigned int ulTestP; + unsigned int ulTestM; + unsigned int ulTestN; + unsigned int ulPLLFreqRef; + + ulVCOMax = 320000; + ulVCOMin = 160000; + ulPLLFreqRef = 25000; + + ulFDelta = 0xFFFFFFFF; + /* Permited delta is 0.5% as VESA Specification */ + ulFPermitedDelta = lFo * 5 / 1000; + + /* Then we need to minimize the M while staying within 0.5% */ + for (ulTestP = 8; ulTestP > 0; ulTestP >>= 1) { + if ((lFo * ulTestP) > ulVCOMax) continue; + if ((lFo * ulTestP) < ulVCOMin) continue; + + for (ulTestN = 17; ulTestN <= 256; ulTestN++) { + for (ulTestM = 1; ulTestM <= 32; ulTestM++) { + ulComputedFo = (ulPLLFreqRef * ulTestN) / (ulTestM * ulTestP); + if (ulComputedFo > lFo) + ulFTmpDelta = ulComputedFo - lFo; + else + ulFTmpDelta = lFo - ulComputedFo; + + if (ulFTmpDelta < ulFDelta) { + ulFDelta = ulFTmpDelta; + *M = ulTestM - 1; + *N = ulTestN - 1; + *P = ulTestP - 1; + } + } + } + } +} + + /** * Calculate the PLL settings (m, n, p, s). * @@ -104,6 +150,8 @@ MGAGCalcClock ( ScrnInfoPtr pScrn, long f_out, in_div_max = 31; post_div_max = 7; break; + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: case PCI_CHIP_MGAG100: case PCI_CHIP_MGAG100_PCI: case PCI_CHIP_MGAG200: @@ -193,13 +241,23 @@ MGAGSetPCLK( ScrnInfoPtr pScrn, long f_out ) return; } - /* Do the calculations for m, n, p and s */ - MGAGCalcClock( pScrn, f_out, &m, &n, &p, &s ); + if ((pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) || + (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI)) { + MGAG200SEComputePLLParam(pScrn, f_out, &m, &n, &p); - /* Values for the pixel clock PLL registers */ - pReg->DacRegs[ MGA1064_PIX_PLLC_M ] = m & 0x1F; - pReg->DacRegs[ MGA1064_PIX_PLLC_N ] = n & 0x7F; - pReg->DacRegs[ MGA1064_PIX_PLLC_P ] = (p & 0x07) | ((s & 0x03) << 3); + pReg->DacRegs[ MGA1064_PIX_PLLC_M ] = m; + pReg->DacRegs[ MGA1064_PIX_PLLC_N ] = n; + pReg->DacRegs[ MGA1064_PIX_PLLC_P ] = p; + } else { + /* Do the calculations for m, n, p and s */ + MGAGCalcClock( pScrn, f_out, &m, &n, &p, &s ); + + /* Values for the pixel clock PLL registers */ + pReg->DacRegs[ MGA1064_PIX_PLLC_M ] = m & 0x1F; + pReg->DacRegs[ MGA1064_PIX_PLLC_N ] = n & 0x7F; + pReg->DacRegs[ MGA1064_PIX_PLLC_P ] = (p & 0x07) | + ((s & 0x03) << 3); + } } /* @@ -349,6 +407,20 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode) pReg->Option &= ~(1 << 14); pReg->Option2 = 0x01003000; break; + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: +#ifdef USEMGAHAL + MGA_HAL(break;); +#endif + pReg->DacRegs[ MGA1064_VREF_CTL ] = 0x03; + pReg->DacRegs[ MGA1064_PIX_CLK_CTL ] = 0x01; + pReg->DacRegs[ MGA1064_MISC_CTL ] = 0x19; + if(pMga->HasSDRAM) + pReg->Option = 0x40499121; + else + pReg->Option = 0x4049cd21; + pReg->Option2 = 0x00008000; + break; case PCI_CHIP_MGAG200: case PCI_CHIP_MGAG200_PCI: default: @@ -688,6 +760,10 @@ MGA_NOT_HAL( ((i == 0x2c) || (i == 0x2d) || (i == 0x2e) || (i == 0x4c) || (i == 0x4d) || (i == 0x4e)))) continue; + if (((pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) || + (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI)) && + (i == 0x2C) || (i == 0x2D) || (i == 0x2E)) + continue; outMGAdac(i, mgaReg->DacRegs[i]); } @@ -722,11 +798,16 @@ MGA_NOT_HAL( for (i = 0; i < 6; i++) OUTREG16(0x1FDE, (mgaReg->ExtVga[i] << 8) | i); - /* - * This function handles restoring the generic VGA registers. - */ - vgaHWRestore(pScrn, vgaReg, + /* This handles restoring the generic VGA registers. */ + if ((pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) || + (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI)) { + vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); + if (restoreFonts) + MGAG200SERestoreFonts(pScrn, vgaReg); + } else { + vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE | (restoreFonts ? VGA_SR_FONTS : 0)); + } MGAGRestorePalette(pScrn, vgaReg->DAC); /* @@ -819,7 +900,15 @@ MGAGSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, * This function will handle creating the data structure and filling * in the generic VGA portion. */ - vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | (saveFonts ? VGA_SR_FONTS : 0)); + if ((pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) || + (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI)) { + vgaHWSave(pScrn, vgaReg, VGA_SR_MODE); + if (saveFonts) + MGAG200SESaveFonts(pScrn, vgaReg); + } else { + vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | + (saveFonts ? VGA_SR_FONTS : 0)); + } MGAGSavePalette(pScrn, vgaReg->DAC); /* * Work around another bug in HALlib: it doesn't restore the @@ -1024,8 +1113,13 @@ MGAG_ddc1Read(ScrnInfoPtr pScrn) outMGAdacmsk(MGA1064_GEN_IO_CTL, ~(DDC_P1_SCL_MASK | DDC_P1_SDA_MASK), 0); /* wait for Vsync */ - while( INREG( MGAREG_Status ) & 0x08 ); - while( ! (INREG( MGAREG_Status ) & 0x08) ); + if ((pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) || + (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI)) { + usleep(4); + } else { + while( INREG( MGAREG_Status ) & 0x08 ); + while( ! (INREG( MGAREG_Status ) & 0x08) ); + } /* Get the result */ val = (inMGAdac(MGA1064_GEN_IO_DATA) & DDC_P1_SDA_MASK); diff --git a/src/mga_dga.c b/src/mga_dga.c index e728484..c75ef0c 100644 --- a/src/mga_dga.c +++ b/src/mga_dga.c @@ -154,8 +154,16 @@ SECOND_PASS: mode->imageWidth = pitch; mode->imageHeight = pMga->FbUsableSize / mode->bytesPerScanline; mode->pixmapWidth = pitch; - mode->pixmapHeight = (min(pMga->FbUsableSize, 16*1024*1024)) / - mode->bytesPerScanline; + switch (pMga->Chipset) { + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: + mode->pixmapHeight = (min(pMga->FbUsableSize, 1*1024*1024)) / + mode->bytesPerScanline; + break; + default: + mode->pixmapHeight = (min(pMga->FbUsableSize, 16*1024*1024)) / + mode->bytesPerScanline; + } mode->maxViewportX = mode->imageWidth - mode->viewportWidth; mode->maxViewportY = (pMga->FbUsableSize / mode->bytesPerScanline) - mode->viewportHeight; diff --git a/src/mga_driver.c b/src/mga_driver.c index 1f1a525..a5c78b2 100644 --- a/src/mga_driver.c +++ b/src/mga_driver.c @@ -169,6 +169,8 @@ static SymTabRec MGAChipsets[] = { { PCI_CHIP_MGAG100_PCI, "mgag100 PCI" }, { PCI_CHIP_MGAG200, "mgag200" }, { PCI_CHIP_MGAG200_PCI, "mgag200 PCI" }, + { PCI_CHIP_MGAG200_SE_A_PCI, "mgag200 SE A PCI" }, + { PCI_CHIP_MGAG200_SE_B_PCI, "mgag200 SE B PCI" }, { PCI_CHIP_MGAG400, "mgag400" }, { PCI_CHIP_MGAG550, "mgag550" }, {-1, NULL } @@ -183,6 +185,10 @@ static PciChipsets MGAPciChipsets[] = { { PCI_CHIP_MGAG100_PCI, PCI_CHIP_MGAG100_PCI,(resRange*)RES_SHARED_VGA }, { PCI_CHIP_MGAG200, PCI_CHIP_MGAG200, (resRange*)RES_SHARED_VGA }, { PCI_CHIP_MGAG200_PCI, PCI_CHIP_MGAG200_PCI,(resRange*)RES_SHARED_VGA }, + { PCI_CHIP_MGAG200_SE_B_PCI, PCI_CHIP_MGAG200_SE_B_PCI, + (resRange*)RES_SHARED_VGA }, + { PCI_CHIP_MGAG200_SE_A_PCI, PCI_CHIP_MGAG200_SE_A_PCI, + (resRange*)RES_SHARED_VGA }, { PCI_CHIP_MGAG400, PCI_CHIP_MGAG400, (resRange*)RES_SHARED_VGA }, { PCI_CHIP_MGAG550, PCI_CHIP_MGAG550, (resRange*)RES_SHARED_VGA }, { -1, -1, (resRange*)RES_UNDEFINED } @@ -755,6 +761,10 @@ MGACountRam(ScrnInfoPtr pScrn) } ProbeSize = 32768; break; + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: + ProbeSize = 4096; + break; case PCI_CHIP_MGAG200: case PCI_CHIP_MGAG200_PCI: if(biosInfo) { @@ -793,17 +803,71 @@ MGACountRam(ScrnInfoPtr pScrn) tmp = INREG8(MGAREG_CRTCEXT_DATA); OUTREG8(MGAREG_CRTCEXT_DATA, tmp | 0x80); - /* write, read and compare method - split into two loops to make it more reliable on RS/6k -ReneR */ - for(i = ProbeSize; i > 2048; i -= 2048) { - base[(i * 1024) - 1] = 0xAA; - } - OUTREG8(MGAREG_CRTC_INDEX, 0); /* flush the cache */ - usleep(4); /* twart write combination */ - for(i = ProbeSize; i > 2048; i -= 2048) { - if(base[(i * 1024) - 1] == 0xAA) { - SizeFound = i; - break; + /* apparently the G200SE doesn't have a BIOS to read */ + if ((pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) || + (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI)) { + + CARD32 MemoryAt0, MemoryAt1, Offset; + CARD32 FirstMemoryVal1, FirstMemoryVal2; + CARD32 SecondMemoryVal1, SecondMemoryVal2; + CARD32 TestMemoryLocA, TestMemoryLocB; + CARD32 TestMemoryLoc0, TestMemoryLoc1; + CARD32 TestA, TestB; + + MemoryAt0 = base[0]; + MemoryAt1 = base[1]; + base[0] = 0; + base[1] = 0; + + for (Offset = 0x100000; Offset < (ProbeSize * 1024); + Offset += 0x1000) { + FirstMemoryVal1 = base[Offset]; + FirstMemoryVal2 = base[Offset+1]; + SecondMemoryVal1 = base[Offset+0x100]; + SecondMemoryVal2 = base[Offset+0x101]; + + base[Offset] = 0x55; + base[Offset+1] = 0xaa; + base[Offset+0x100] = 0x55; + base[Offset+0x101] = 0xaa; + + OUTREG(MGAREG_CRTC_INDEX, 0); + usleep(8); + + TestMemoryLocA = base[Offset]; + TestMemoryLocB = base[Offset+1]; + TestMemoryLoc0 = base[0]; + TestMemoryLoc1 = base[1]; + + base[Offset] = FirstMemoryVal1; + base[Offset+1] = FirstMemoryVal2; + base[Offset+0x100] = SecondMemoryVal1; + base[Offset+0x101] = SecondMemoryVal2; + + TestA = ((TestMemoryLocB << 8) + TestMemoryLocA); + TestB = ((TestMemoryLoc1 << 8) + TestMemoryLoc0); + if ((TestA != 0xAA55) || (TestB)) { + break; + } + } + + base[0] = MemoryAt0; + base[1] = MemoryAt1; + + SizeFound = (Offset / 1024) - 64; + } else { + /* write, read and compare method + split into two loops to make it more reliable on RS/6k -ReneR */ + for(i = ProbeSize; i > 2048; i -= 2048) { + base[(i * 1024) - 1] = 0xAA; + } + OUTREG8(MGAREG_CRTC_INDEX, 0); /* flush the cache */ + usleep(4); /* twart write combination */ + for(i = ProbeSize; i > 2048; i -= 2048) { + if(base[(i * 1024) - 1] == 0xAA) { + SizeFound = i; + break; + } } } @@ -1589,6 +1653,8 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) case PCI_CHIP_MGAG100_PCI: case PCI_CHIP_MGAG200: case PCI_CHIP_MGAG200_PCI: + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: case PCI_CHIP_MGAG400: case PCI_CHIP_MGAG550: MGAGSetupFuncs(pScrn); @@ -1817,6 +1883,8 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) case PCI_CHIP_MGAG400: case PCI_CHIP_MGAG200: case PCI_CHIP_MGAG200_PCI: + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: pMga->SrcOrg = 0; pMga->DstOrg = 0; break; @@ -1977,6 +2045,8 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) break; case PCI_CHIP_MGAG200: case PCI_CHIP_MGAG200_PCI: + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: case PCI_CHIP_MGAG400: case PCI_CHIP_MGAG550: maxPitch = 4096; @@ -2604,7 +2674,13 @@ MGAFillModeInfoStruct(ScrnInfoPtr pScrn, DisplayModePtr mode) } else { pMga->pMgaModeInfo->flOutput = MGAMODEINFO_FORCE_PITCH; if (digital1) { - pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_DIGITAL1; + if ((pMga->Chipset == PCI_CHIP_MGAG200) || + (pMga->Chipset == PCI_CHIP_MGAG200_PCI)) { + pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_FLATPANEL1; + pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_DIGITAL2; + } else { + pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_DIGITAL1; + } } else if (tv1) { pMga->pMgaModeInfo->flOutput |= MGAMODEINFO_TV; } else { @@ -2737,6 +2813,8 @@ MGA_HAL( case PCI_CHIP_MGAG100_PCI: case PCI_CHIP_MGAG200: case PCI_CHIP_MGAG200_PCI: + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: case PCI_CHIP_MGAG400: case PCI_CHIP_MGAG550: if(pMga->SecondCrtc == FALSE && pMga->HWCursor == TRUE) { @@ -2925,6 +3003,7 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) int width, height, displayWidth; MGAEntPtr pMgaEnt = NULL; int f; + CARD32 VRTemp, FBTemp; #ifdef XF86DRI MessageType driFrom = X_DEFAULT; #endif @@ -2938,6 +3017,13 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pMga = MGAPTR(pScrn); MGAdac = &pMga->Dac; + if ((pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) || + (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI)) { + VRTemp = pScrn->videoRam; + FBTemp = pMga->FbMapSize; + pScrn->videoRam = 4096; + pMga->FbMapSize = pScrn->videoRam * 1024; + } /* Map the MGA memory and MMIO areas */ if (pMga->FBDev) { @@ -3016,6 +3102,11 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) ); /* MGA_HAL */ #endif } + if ((pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) || + (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI)) { + pScrn->videoRam = VRTemp; + pMga->FbMapSize = FBTemp; + } #ifdef USEMGAHAL MGA_HAL( /* There is a problem in the HALlib: set soft reset bit */ @@ -3053,6 +3144,8 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) case PCI_CHIP_MGAG100_PCI: case PCI_CHIP_MGAG200: case PCI_CHIP_MGAG200_PCI: + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: case PCI_CHIP_MGAG400: case PCI_CHIP_MGAG550: outMGAdac(MGA1064_CURSOR_BASE_ADR_LOW, pMga->FbCursorOffset >> 10); @@ -3160,7 +3253,13 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) * InitGLXVisuals call back. * The DRI does not work when textured video is enabled at this time. */ - if (!xf86ReturnOptValBool(pMga->Options, OPTION_DRI, TRUE)) { + if ((pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) || + (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Not supported by hardware, not initializing the DRI\n"); + pMga->directRenderingEnabled = FALSE; + driFrom = X_PROBED; + } else if (!xf86ReturnOptValBool(pMga->Options, OPTION_DRI, TRUE)) { driFrom = X_CONFIG; } else if ( pMga->NoAccel ) { xf86DrvMsg( pScrn->scrnIndex, X_ERROR, diff --git a/src/mga_macros.h b/src/mga_macros.h index 1c479e6..c8ba847 100644 --- a/src/mga_macros.h +++ b/src/mga_macros.h @@ -65,6 +65,8 @@ while(INREG(MGAREG_DWGSYNC) != MGA_SYNC_XTAG) ; \ #ifdef USEMGAHAL #define HAL_CHIPSETS ((pMga->Chipset == PCI_CHIP_MGAG200_PCI) || \ (pMga->Chipset == PCI_CHIP_MGAG200) || \ + (pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) || \ + (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI) || \ (pMga->Chipset == PCI_CHIP_MGAG400) || \ (pMga->Chipset == PCI_CHIP_MGAG550)) diff --git a/src/mga_merge.c b/src/mga_merge.c index 93710fb..759e4c5 100644 --- a/src/mga_merge.c +++ b/src/mga_merge.c @@ -362,6 +362,8 @@ MGAPreInitMergedFB(ScrnInfoPtr pScrn1, int flags) case PCI_CHIP_MGAG100_PCI: case PCI_CHIP_MGAG200: case PCI_CHIP_MGAG200_PCI: + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: case PCI_CHIP_MGAG400: case PCI_CHIP_MGAG550: MGAGSetupFuncs(pScrn); @@ -511,6 +513,8 @@ MGAPreInitMergedFB(ScrnInfoPtr pScrn1, int flags) break; case PCI_CHIP_MGAG200: case PCI_CHIP_MGAG200_PCI: + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: case PCI_CHIP_MGAG400: case PCI_CHIP_MGAG550: maxPitch = 4096; diff --git a/src/mga_storm.c b/src/mga_storm.c index 366bddb..187aa93 100644 --- a/src/mga_storm.c +++ b/src/mga_storm.c @@ -645,6 +645,11 @@ Bool mgaAccelInit( ScreenPtr pScreen ) TRANSC_SOLID_FILL | USE_RECTS_FOR_LINES; break; + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: + doRender = FALSE; + pMga->AccelFlags = TRANSC_SOLID_FILL | TWO_PASS_COLOR_EXPAND; + break; case PCI_CHIP_MGAG400: case PCI_CHIP_MGAG550: if(pMga->SecondCrtc == TRUE) { @@ -853,8 +858,17 @@ Bool mgaAccelInit( ScreenPtr pScreen ) pMga->MaxFastBlitY = maxFastBlitMem / (pScrn->displayWidth * pMga->CurrentLayout.bitsPerPixel / 8); } - maxlines = (min(pMga->FbUsableSize, 16*1024*1024)) / - (pScrn->displayWidth * pMga->CurrentLayout.bitsPerPixel / 8); + switch (pMga->Chipset) { + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: + maxlines = (min(pMga->FbUsableSize, 1*1024*1024)) / + (pScrn->displayWidth * pMga->CurrentLayout.bitsPerPixel / 8); + break; + default: + maxlines = (min(pMga->FbUsableSize, 16*1024*1024)) / + (pScrn->displayWidth * pMga->CurrentLayout.bitsPerPixel / 8); + break; + } #ifdef XF86DRI if ( pMga->directRenderingEnabled ) { @@ -1190,6 +1204,8 @@ void MGAStormEngineInit( ScrnInfoPtr pScrn ) case PCI_CHIP_MGAG400: case PCI_CHIP_MGAG200: case PCI_CHIP_MGAG200_PCI: + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: pMga->SrcOrg = 0; OUTREG(MGAREG_SRCORG, pMga->realSrcOrg); OUTREG(MGAREG_DSTORG, pMga->DstOrg); diff --git a/src/mga_vga.c b/src/mga_vga.c new file mode 100644 index 0000000..26fcefc --- /dev/null +++ b/src/mga_vga.c @@ -0,0 +1,221 @@ +#include "misc.h" +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "vgaHW.h" +#include "compiler.h" +#include "xf86cmap.h" + +#define TEXT_AMOUNT 16384 +#define FONT_AMOUNT (8*8192) + +void +MGAG200SERestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore) +{ + vgaHWPtr hwp = VGAHWPTR(scrninfp); + int savedIOBase; + unsigned char miscOut, attr10, gr1, gr3, gr4, gr5, gr6, gr8, seq2, seq4; + Bool doMap = FALSE; + + /* If nothing to do, return now */ + if (!hwp->FontInfo1 && !hwp->FontInfo2 && !hwp->TextInfo) + return; + + if (hwp->Base == NULL) { + doMap = TRUE; + if (!vgaHWMapMem(scrninfp)) { + xf86DrvMsg(scrninfp->scrnIndex, X_ERROR, + "vgaHWRestoreFonts: vgaHWMapMem() failed\n"); + return; + } + } + + /* save the registers that are needed here */ + miscOut = hwp->readMiscOut(hwp); + attr10 = hwp->readAttr(hwp, 0x10); + gr1 = hwp->readGr(hwp, 0x01); + gr3 = hwp->readGr(hwp, 0x03); + gr4 = hwp->readGr(hwp, 0x04); + gr5 = hwp->readGr(hwp, 0x05); + gr6 = hwp->readGr(hwp, 0x06); + gr8 = hwp->readGr(hwp, 0x08); + seq2 = hwp->readSeq(hwp, 0x02); + seq4 = hwp->readSeq(hwp, 0x04); + + /* save hwp->IOBase and temporarily set it for colour mode */ + savedIOBase = hwp->IOBase; + hwp->IOBase = VGA_IOBASE_COLOR; + + /* Force into colour mode */ + hwp->writeMiscOut(hwp, miscOut | 0x01); + + vgaHWBlankScreen(scrninfp, FALSE); + + /* + * here we temporarily switch to 16 colour planar mode, to simply + * copy the font-info and saved text. + * + * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly! + */ +#if 0 + hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */ +#endif + if (scrninfp->depth == 4) { + /* GJA */ + hwp->writeGr(hwp, 0x03, 0x00); /* don't rotate, write unmodified */ + hwp->writeGr(hwp, 0x08, 0xFF); /* write all bits in a byte */ + hwp->writeGr(hwp, 0x01, 0x00); /* all planes come from CPU */ + } + + if (hwp->FontInfo1) { + hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */ + hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ + hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */ + hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ + hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ + slowbcopy_tobus(hwp->FontInfo1, hwp->Base, FONT_AMOUNT); + } + + if (hwp->FontInfo2) { + hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */ + hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ + hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */ + hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ + hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ + slowbcopy_tobus(hwp->FontInfo2, hwp->Base, FONT_AMOUNT); + } + + if (hwp->TextInfo) { + hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */ + hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ + hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */ + hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ + hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ + slowbcopy_tobus(hwp->TextInfo, hwp->Base, TEXT_AMOUNT); + hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */ + hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ + hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */ + hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ + hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ + slowbcopy_tobus((unsigned char *)hwp->TextInfo + TEXT_AMOUNT, + hwp->Base, TEXT_AMOUNT); + } + + /* restore the registers that were changed */ + hwp->writeMiscOut(hwp, miscOut); + hwp->writeAttr(hwp, 0x10, attr10); + hwp->writeGr(hwp, 0x01, gr1); + hwp->writeGr(hwp, 0x03, gr3); + hwp->writeGr(hwp, 0x04, gr4); + hwp->writeGr(hwp, 0x05, gr5); + hwp->writeGr(hwp, 0x06, gr6); + hwp->writeGr(hwp, 0x08, gr8); + hwp->writeSeq(hwp, 0x02, seq2); + hwp->writeSeq(hwp, 0x04, seq4); + hwp->IOBase = savedIOBase; + + vgaHWBlankScreen(scrninfp, TRUE); + + if (doMap) + vgaHWUnmapMem(scrninfp); +} + + +void +MGAG200SESaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save) +{ + vgaHWPtr hwp = VGAHWPTR(scrninfp); + int savedIOBase; + unsigned char miscOut, attr10, gr4, gr5, gr6, seq2, seq4; + Bool doMap = FALSE; + + if (hwp->Base == NULL) { + doMap = TRUE; + if (!vgaHWMapMem(scrninfp)) { + xf86DrvMsg(scrninfp->scrnIndex, X_ERROR, + "vgaHWSaveFonts: vgaHWMapMem() failed\n"); + return; + } + } + + /* If in graphics mode, don't save anything */ + attr10 = hwp->readAttr(hwp, 0x10); + if (attr10 & 0x01) + return; + + /* save the registers that are needed here */ + miscOut = hwp->readMiscOut(hwp); + gr4 = hwp->readGr(hwp, 0x04); + gr5 = hwp->readGr(hwp, 0x05); + gr6 = hwp->readGr(hwp, 0x06); + seq2 = hwp->readSeq(hwp, 0x02); + seq4 = hwp->readSeq(hwp, 0x04); + + /* save hwp->IOBase and temporarily set it for colour mode */ + savedIOBase = hwp->IOBase; + hwp->IOBase = VGA_IOBASE_COLOR; + + /* Force into colour mode */ + hwp->writeMiscOut(hwp, miscOut | 0x01); + + vgaHWBlankScreen(scrninfp, FALSE); + + /* + * get the character sets, and text screen if required + */ + /* + * Here we temporarily switch to 16 colour planar mode, to simply + * copy the font-info + * + * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly! + */ +#if 0 + hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */ +#endif + if (hwp->FontInfo1 || (hwp->FontInfo1 = xalloc(FONT_AMOUNT))) { + hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */ + hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ + hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */ + hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ + hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ + slowbcopy_frombus(hwp->Base, hwp->FontInfo1, FONT_AMOUNT); + } + if (hwp->FontInfo2 || (hwp->FontInfo2 = xalloc(FONT_AMOUNT))) { + hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */ + hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ + hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */ + hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ + hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ + slowbcopy_frombus(hwp->Base, hwp->FontInfo2, FONT_AMOUNT); + } + if (hwp->TextInfo || (hwp->TextInfo = xalloc(2 * TEXT_AMOUNT))) { + hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */ + hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ + hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */ + hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ + hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ + slowbcopy_frombus(hwp->Base, hwp->TextInfo, TEXT_AMOUNT); + hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */ + hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */ + hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */ + hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */ + hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */ + slowbcopy_frombus(hwp->Base, + (unsigned char *)hwp->TextInfo + TEXT_AMOUNT, TEXT_AMOUNT); + } + + /* Restore clobbered registers */ + hwp->writeAttr(hwp, 0x10, attr10); + hwp->writeGr(hwp, 0x04, gr4); + hwp->writeGr(hwp, 0x05, gr5); + hwp->writeGr(hwp, 0x06, gr6); + hwp->writeSeq(hwp, 0x02, seq2); + hwp->writeSeq(hwp, 0x04, seq4); + hwp->writeMiscOut(hwp, miscOut); + hwp->IOBase = savedIOBase; + + vgaHWBlankScreen(scrninfp, TRUE); + + if (doMap) + vgaHWUnmapMem(scrninfp); +} -- cgit v1.2.3