mga driver patches

Stuart Kreitman Stuart.Kreitman at Sun.COM
Mon Feb 26 13:21:32 PST 2007


Ben:

Thank you for doing this.  We need to create an entry in 
bugs.freedesktop.org to track this, and attach these diffs to it.

(Lurkers:  Jay and I have been working with ServerEngines on this issue 
for a few weeks)

Stuart Kreitman
Sun Microsystems

btouchet wrote:
> Hi,
>
> Here is an update to support new chips from ServerEngines, with graphics
> portion is based on G200 GPU in the mga driver.
>
> Ben
>
>   
> ------------------------------------------------------------------------
>
> diff -ur xf86-video-mga-X11R7.2-1.4.6.1/src/mga_dacG.c mga/src/mga_dacG.c
> --- xf86-video-mga-X11R7.2-1.4.6.1/src/mga_dacG.c	2007-01-09 15:39:23.000000000 -0500
> +++ mga/src/mga_dacG.c	2007-02-16 13:30:53.000000000 -0500
> @@ -60,6 +60,7 @@
>  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);
>  
>  static void
>  MGAG200SEComputePLLParam(ScrnInfoPtr pScrn, long lFo, int *M, int *N, int *P)
> @@ -810,15 +811,15 @@
>  
>  	   /* This handles restoring the generic VGA registers. */
>  	   if (pMga->is_G200SE) {
> -	      vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
> +	      MGAG200SERestoreMode(pScrn, vgaReg);
>  	      if (restoreFonts)
>  	         MGAG200SERestoreFonts(pScrn, vgaReg);
>  	   } else {
>  	      vgaHWRestore(pScrn, vgaReg,
>  			VGA_SR_MODE | (restoreFonts ? VGA_SR_FONTS : 0));
>  	   }
> -  	   MGAGRestorePalette(pScrn, vgaReg->DAC); 
> -	   
> +  	   MGAGRestorePalette(pScrn, vgaReg->DAC);
> +
>  	   /*
>  	    * this is needed to properly restore start address
>  	    */
> @@ -904,13 +905,13 @@
>  	 * Code is needed to get back to bank zero.
>  	 */
>  	OUTREG16(0x1FDE, 0x0004);
> -	
> +
>  	/*
>  	 * This function will handle creating the data structure and filling
>  	 * in the generic VGA portion.
>  	 */
>  	if (pMga->is_G200SE) {
> -	    vgaHWSave(pScrn, vgaReg, VGA_SR_MODE);
> +	    MGAG200SESaveMode(pScrn, vgaReg);
>  	    if (saveFonts)
>  		MGAG200SESaveFonts(pScrn, vgaReg);
>  	} else {
> 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
> @@ -821,6 +856,16 @@
>  	MGAMapMem(pScrn);
>  	base = pMga->FbBase;
>  
> +	if (pMga->is_G200SE) {
> +        OUTREG(MGAREG_SEQ_INDEX, 0x01);
> +        seq1 = INREG8(MGAREG_SEQ_DATA);
> +        seq1 |= 0x20;
> +        MGAWAITVSYNC();
> +        MGAWAITBUSY();
> +        OUTREG(MGAREG_SEQ_DATA, seq1);
> +        usleep(20000);
> +    }
> +
>  	/* turn MGA mode on - enable linear frame buffer (CRTCEXT3) */
>  	OUTREG8(MGAREG_CRTCEXT_INDEX, 3);
>  	tmp = INREG8(MGAREG_CRTCEXT_DATA);
> @@ -896,6 +954,16 @@
>  	OUTREG8(MGAREG_CRTCEXT_INDEX, 3);
>  	OUTREG8(MGAREG_CRTCEXT_DATA, tmp);
>  
> +	if (pMga->is_G200SE) {
> +        OUTREG(MGAREG_SEQ_INDEX, 0x01);
> +        seq1 = INREG8(MGAREG_SEQ_DATA);
> +        seq1 &= ~0x20;
> +        MGAWAITVSYNC();
> +        MGAWAITBUSY();
> +        OUTREG(MGAREG_SEQ_DATA, seq1);
> +        usleep(20000);
> +    }
> +
>  	MGAUnmapMem(pScrn);
>     }
>     return SizeFound;
> @@ -941,6 +1009,10 @@
>      }
>  #endif /* MGAuseI2C */
>  
> +  if (pMga->is_G200SE) {
> +    return NULL;
> +  }
> +
>    /* Map the MGA memory and MMIO areas */
>    if (!MGAMapMem(pScrn))
>      return NULL;
> @@ -1286,6 +1360,7 @@
>  	|| (pMga->Chipset == PCI_CHIP_MGAG550);
>      pMga->is_G200SE = (pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI)
>  	|| (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI);
> +    pMga->is_G200SE_A = (pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI);
>      pMga->is_HAL_chipset = ((pMga->Chipset == PCI_CHIP_MGAG200_PCI) ||
>  		  (pMga->Chipset == PCI_CHIP_MGAG200) ||
>  		  (pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) ||
> @@ -1451,13 +1545,22 @@
>      /* Collect all of the relevant option flags (fill in pScrn->options) */
>      xf86CollectOptions(pScrn, NULL);
>  
> +    if (pMga->is_G200SE) {
> +         /* Disable MTRR support on PCIe systems */
> +         temp = pciReadLong(pMga->PciTag, 0xDC);
> +         if ((temp & 0x0000FF00) != 0x0) {
> +             xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling MTRR support.\n");
> +             pScrn->options = xf86ReplaceBoolOption(pScrn->options, "MTRR", FALSE);
> +         }
> +    }
> +
>      /* 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 (pMga->Chipset >= PCI_CHIP_MGAG400
> @@ -2135,17 +2238,22 @@
>  	MGAFreeRec(pScrn);
>  	return FALSE;
>      }
> +
> +    if ((pScrn->modes->VDisplay > 1600) && 
> +        (pScrn->modes->HDisplay > 1200) &&
> +        (pMga->is_G200SE_A)) {
> +        return FALSE;
> +    }
>  #ifdef USEMGAHAL
>      MGA_HAL(
> -
>      if(pMga->SecondCrtc == FALSE) {
> -	
> +
>          pMga->pBoard = xalloc(sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize());
>          pMga->pClientStruct = xalloc(sizeof(CLIENTDATA));
>          pMga->pClientStruct->pMga = (MGAPtr) pMga;
>  
>          MGAMapMem(pScrn);
> -	/* 
> +	/*
>  	 * For some reason the MGAOPM_DMA_BLIT bit needs to be set
>  	 * on G200 before opening the HALlib. I don't know why.
>  	 * MATROX: hint, hint.
> @@ -2787,13 +2913,17 @@
>  	return FALSE;
>  
>      /* Program the registers */
> -    vgaHWProtect(pScrn, TRUE);
> +    if (pMga->is_G200SE) {
> +        MGAG200SEHWProtect(pScrn, TRUE);
> +    } else {
> +        vgaHWProtect(pScrn, TRUE);
> +    }
>      vgaReg = &hwp->ModeReg;
>      mgaReg = &pMga->ModeReg;
>  #ifdef USEMGAHAL
> -    MGA_HAL( 
> +    MGA_HAL(
>          MGAFillModeInfoStruct(pScrn,mode);
> -                    
> +
>          /* Validate the parameters */
>          if ((status = MGAValidateMode(pMga->pBoard, pMga->pMgaModeInfo)) != 0) {
>              xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
> @@ -2890,7 +3036,7 @@
>      		  outMGAdac(MGA1064_COL_KEY_LSB,pMga->colorKey);
>    		  outMGAdac(MGA1064_COL_KEY_MSK_MSB,0xFF);
>    		  outMGAdac(MGA1064_COL_KEY_MSB,0xFF);
> -	      }		
> +	      }
>  	      break;
>  	    default:
>  	      break;
> @@ -2903,7 +3049,11 @@
>      MGAStormSync(pScrn);
>      MGAStormEngineInit(pScrn);
>  
> -    vgaHWProtect(pScrn, FALSE);
> +    if (pMga->is_G200SE) {
> +        MGAG200SEHWProtect(pScrn, TRUE);
> +    } else {
> +        vgaHWProtect(pScrn, TRUE);
> +    }
>  
>      if (xf86IsPc98()) {
>  	if (pMga->Chipset == PCI_CHIP_MGA2064)
> @@ -2999,16 +3162,20 @@
>      if((!xf86IsEntityShared(pScrn->entityList[0]) && !pMga->SecondCrtc)
>         || pMga->SecondCrtc || pMga->MergedFB) {
>  	/*       if(pMga->MergedFB) {
> -		 if(pMga->pScrn2) 
> +		 if(pMga->pScrn2)
>                   MGARestoreSecondCrtc(pMga->pScrn2);
>  		 } else*/
>  	MGARestoreSecondCrtc(pScrn);
>  	/* if we are second instance of driver, we've done our job, exit */
>  	if(pMga->SecondCrtc) return;
>      }
> -    
> +
>      /* Only restore text mode fonts/text for the primary card */
> -    vgaHWProtect(pScrn, TRUE);
> +    if (pMga->is_G200SE) {
> +        MGAG200SEHWProtect(pScrn, TRUE);
> +    } else {
> +        vgaHWProtect(pScrn, TRUE);
> +    }
>      if (pMga->Primary) {
>  #ifdef USEMGAHAL
>  	MGA_HAL(
> @@ -3022,7 +3189,11 @@
>      } else {
>          vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
>      }
> -    vgaHWProtect(pScrn, FALSE);
> +    if (pMga->is_G200SE) {
> +        MGAG200SEHWProtect(pScrn, TRUE);
> +    } else {
> +        vgaHWProtect(pScrn, TRUE);
> +    }
>  }
>  
>  
> @@ -4063,7 +4234,10 @@
>  	/* XXX Prefer an implementation that doesn't depend on VGA specifics */
>  	OUTREG8(MGAREG_SEQ_INDEX, 0x01);	/* Select SEQ1 */
>  	seq1 |= INREG8(MGAREG_SEQ_DATA) & ~0x20;
> -	OUTREG8(MGAREG_SEQ_DATA, seq1);
> +    MGAWAITVSYNC();
> +    MGAWAITBUSY();
> + 	OUTREG8(MGAREG_SEQ_DATA, seq1);
> +    usleep(20000);
>  	OUTREG8(MGAREG_CRTCEXT_INDEX, 0x01);	/* Select CRTCEXT1 */
>  	crtcext1 |= INREG8(MGAREG_CRTCEXT_DATA) & ~0x30;
>  	OUTREG8(MGAREG_CRTCEXT_DATA, crtcext1);
> diff -ur xf86-video-mga-X11R7.2-1.4.6.1/src/mga.h mga/src/mga.h
> --- xf86-video-mga-X11R7.2-1.4.6.1/src/mga.h	2007-01-08 18:45:22.000000000 -0500
> +++ mga/src/mga.h	2007-02-16 13:52:17.000000000 -0500
> @@ -147,6 +147,42 @@
>  	    outMGAdreg(MGA1064_DATA, tmp | (val)); \
>  	} while (0)
>  
> +#define MGAWAITVSYNC() \
> +    {\
> +	    unsigned int uiCount = 0; \
> +    	unsigned int uiStatus = 0; \
> +	    do \
> +    	{ \
> +	        uiStatus = INREG( MGAREG_Status ); \
> +	        uiCount++; \
> +    	} \
> +	    while( ( uiStatus & 0x08 ) && (uiCount < 250000) );\
> +	    uiCount = 0; \
> +    	uiStatus = 0; \
> +	    do \
> +    	{ \
> +	        uiStatus = INREG( MGAREG_Status ); \
> +	        uiCount++; \
> +    	} \
> +	    while( !( uiStatus & 0x08 ) && (uiCount < 250000) );\
> +    }
> +
> +#define MGAWAITBUSY() \
> +    { \
> +    	unsigned int uiCount = 0; \
> +	    unsigned int uiStatus = 0; \
> +    	do \
> +	    { \
> +    	    uiStatus = INREG8( MGAREG_Status + 2 ); \
> +	        uiCount++; \
> +    	} \
> +	    while( ( uiStatus & 0x01 ) && (uiCount < 500000) ); \
> +    }
> +
> +#ifndef MAX_BW
> +#define MAX_BW 0x10000000
> +#endif
> +
>  #define PORT_OFFSET 	(0x1F00 - 0x300)
>  
>  #define MGA_VERSION 4000
> @@ -391,6 +427,7 @@
>  
>      int is_Gx50:1;
>      int is_G200SE:1;
> +    int is_G200SE_A:1;
>      int is_HAL_chipset:1;
>  
>      Bool		Primary;
> diff -ur xf86-video-mga-X11R7.2-1.4.6.1/src/mga_vga.c mga/src/mga_vga.c
> --- xf86-video-mga-X11R7.2-1.4.6.1/src/mga_vga.c	2007-01-08 18:45:22.000000000 -0500
> +++ mga/src/mga_vga.c	2007-02-20 10:49:26.000000000 -0500
> @@ -1,9 +1,13 @@
> +
> +#include "X11/X.h"
>  #include "misc.h"
>  #include "xf86.h"
>  #include "xf86_OSproc.h"
>  #include "vgaHW.h"
>  #include "compiler.h"
>  #include "xf86cmap.h"
> +#include "mga.h"
> +#include "mga_reg.h"
>  
>  #define TEXT_AMOUNT 16384
>  #define FONT_AMOUNT (8*8192)
> @@ -12,9 +16,11 @@
>  MGAG200SERestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore)
>  {
>      vgaHWPtr hwp = VGAHWPTR(scrninfp);
> +    MGAPtr pMga = MGAPTR(scrninfp);
>      int savedIOBase;
>      unsigned char miscOut, attr10, gr1, gr3, gr4, gr5, gr6, gr8, seq2, seq4;
>      Bool doMap = FALSE;
> +    unsigned char scrn;
>  
>      /* If nothing to do, return now */
>      if (!hwp->FontInfo1 && !hwp->FontInfo2 && !hwp->TextInfo)
> @@ -24,7 +30,7 @@
>  	doMap = TRUE;
>  	if (!vgaHWMapMem(scrninfp)) {
>  	    xf86DrvMsg(scrninfp->scrnIndex, X_ERROR,
> -		    "vgaHWRestoreFonts: vgaHWMapMem() failed\n");
> +		       "vgaHWRestoreFonts: vgaHWMapMem() failed\n");
>  	    return;
>  	}
>      }
> @@ -48,7 +54,14 @@
>      /* Force into colour mode */
>      hwp->writeMiscOut(hwp, miscOut | 0x01);
>  
> -    vgaHWBlankScreen(scrninfp, FALSE);
> +    scrn = hwp->readSeq(hwp, 0x01);
> +    scrn |= 0x20;/* blank screen */
> +    vgaHWSeqReset(hwp, TRUE);
> +    MGAWAITVSYNC();
> +    MGAWAITBUSY();
> +    hwp->writeSeq(hwp, 0x01, scrn);/* change mode */
> +    usleep(20000);
> +    vgaHWSeqReset(hwp, FALSE);
>  
>      /*
>       * here we temporarily switch to 16 colour planar mode, to simply
> @@ -57,47 +70,39 @@
>       * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
>       */
>  #if 0
> -    hwp->writeAttr(hwp, 0x10, 0x01);   /* graphics mode */
> +    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 */
> +	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 */
>      }
>  
> +	hwp->writeSeq(hwp, 0x04, 0x06);	/* enable plane graphics */
> +	hwp->writeGr(hwp, 0x05, 0x00);	/* write mode 0, read mode 0 */
> +	hwp->writeGr(hwp, 0x06, 0x05);	/* set graphics */
> +
>      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 */
> +	hwp->writeSeq(hwp, 0x02, 0x04);	/* write to plane 2 */
> +	hwp->writeGr(hwp, 0x04, 0x02);	/* read plane 2 */
>  	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 */
> +	hwp->writeSeq(hwp, 0x02, 0x08);	/* write to plane 3 */
> +	hwp->writeGr(hwp, 0x04, 0x03);	/* read plane 3 */
>  	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 */
> +	hwp->writeSeq(hwp, 0x02, 0x01);	/* write to plane 0 */
> +	hwp->writeGr(hwp, 0x04, 0x00);	/* read plane 0 */
>  	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 */
> +	hwp->writeSeq(hwp, 0x02, 0x02);	/* write to plane 1 */
> +	hwp->writeGr(hwp, 0x04, 0x01);	/* read plane 1 */
>  	slowbcopy_tobus((unsigned char *)hwp->TextInfo + TEXT_AMOUNT,
> -		hwp->Base, TEXT_AMOUNT);
> +			hwp->Base, TEXT_AMOUNT);
>      }
>  
>      /* restore the registers that were changed */
> @@ -113,7 +118,14 @@
>      hwp->writeSeq(hwp, 0x04, seq4);
>      hwp->IOBase = savedIOBase;
>  
> -    vgaHWBlankScreen(scrninfp, TRUE);
> +    scrn = hwp->readSeq(hwp, 0x01);
> +    scrn &= ~0x20;/* enable screen */
> +    vgaHWSeqReset(hwp, TRUE);
> +    MGAWAITVSYNC();
> +    MGAWAITBUSY();
> +    hwp->writeSeq(hwp, 0x01, scrn);/* change mode */
> +    usleep(20000);
> +    vgaHWSeqReset(hwp, FALSE);
>  
>      if (doMap)
>  	vgaHWUnmapMem(scrninfp);
> @@ -124,15 +136,17 @@
>  MGAG200SESaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save)
>  {
>      vgaHWPtr hwp = VGAHWPTR(scrninfp);
> +    MGAPtr pMga = MGAPTR(scrninfp);
>      int savedIOBase;
>      unsigned char miscOut, attr10, gr4, gr5, gr6, seq2, seq4;
>      Bool doMap = FALSE;
> +    unsigned char scrn;
>  
>      if (hwp->Base == NULL) {
>  	doMap = TRUE;
>  	if (!vgaHWMapMem(scrninfp)) {
>  	    xf86DrvMsg(scrninfp->scrnIndex, X_ERROR,
> -		    "vgaHWSaveFonts: vgaHWMapMem() failed\n");
> +		       "vgaHWSaveFonts: vgaHWMapMem() failed\n");
>  	    return;
>  	}
>      }
> @@ -157,7 +171,14 @@
>      /* Force into colour mode */
>      hwp->writeMiscOut(hwp, miscOut | 0x01);
>  
> -    vgaHWBlankScreen(scrninfp, FALSE);
> +    scrn = hwp->readSeq(hwp, 0x01);
> +    scrn |= 0x20;/* blank screen */
> +    vgaHWSeqReset(hwp, TRUE);
> +    MGAWAITVSYNC();
> +    MGAWAITBUSY();
> +    hwp->writeSeq(hwp, 0x01, scrn);/* change mode */
> +    usleep(20000);
> +    vgaHWSeqReset(hwp, FALSE);
>  
>      /*
>       * get the character sets, and text screen if required
> @@ -169,36 +190,27 @@
>       * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
>       */
>  #if 0
> -    hwp->writeAttr(hwp, 0x10, 0x01);   /* graphics mode */
> +    hwp->writeAttr(hwp, 0x10, 0x01);	/* graphics mode */
>  #endif
> +	hwp->writeSeq(hwp, 0x04, 0x06);	/* enable plane graphics */
> +	hwp->writeGr(hwp, 0x05, 0x00);	/* write mode 0, read mode 0 */
> +	hwp->writeGr(hwp, 0x06, 0x05);	/* set graphics */
>      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 */
> +	hwp->writeSeq(hwp, 0x02, 0x04);	/* write to plane 2 */
> +	hwp->writeGr(hwp, 0x04, 0x02);	/* read plane 2 */
>  	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 */
> +	hwp->writeSeq(hwp, 0x02, 0x08);	/* write to plane 3 */
> +	hwp->writeGr(hwp, 0x04, 0x03);	/* read plane 3 */
>  	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 */
> +	hwp->writeSeq(hwp, 0x02, 0x01);	/* write to plane 0 */
> +	hwp->writeGr(hwp, 0x04, 0x00);	/* read plane 0 */
>  	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 */
> +	hwp->writeSeq(hwp, 0x02, 0x02);	/* write to plane 1 */
> +	hwp->writeGr(hwp, 0x04, 0x01);	/* read plane 1 */
>  	slowbcopy_frombus(hwp->Base,
>  		(unsigned char *)hwp->TextInfo + TEXT_AMOUNT, TEXT_AMOUNT);
>      }
> @@ -213,8 +225,150 @@
>      hwp->writeMiscOut(hwp, miscOut);
>      hwp->IOBase = savedIOBase;
>  
> -    vgaHWBlankScreen(scrninfp, TRUE);
> +    scrn = hwp->readSeq(hwp, 0x01);
> +    scrn &= ~0x20;/* enable screen */
> +    vgaHWSeqReset(hwp, TRUE);
> +    MGAWAITVSYNC();
> +    MGAWAITBUSY();
> +    hwp->writeSeq(hwp, 0x01, scrn);/* change mode */
> +    usleep(20000);
> +    vgaHWSeqReset(hwp, FALSE);
>  
>      if (doMap)
>  	vgaHWUnmapMem(scrninfp);
>  }
> +
> +
> +void
> +MGAG200SERestoreMode(ScrnInfoPtr scrninfp, vgaRegPtr restore)
> +{
> +    vgaHWPtr hwp = VGAHWPTR(scrninfp);
> +    MGAPtr pMga = MGAPTR(scrninfp);
> +    int i;
> +    unsigned char scrn;
> +
> +    if (restore->MiscOutReg & 0x01)
> +    hwp->IOBase = VGA_IOBASE_COLOR;
> +    else
> +    hwp->IOBase = VGA_IOBASE_MONO;
> +
> +    hwp->writeMiscOut(hwp, restore->MiscOutReg);
> +
> +
> +    for (i = 1; i < restore->numSequencer; i++)
> +    {
> +    MGAWAITVSYNC();
> +    MGAWAITBUSY();
> +	hwp->writeSeq(hwp, i, restore->Sequencer[i]);
> +	usleep(20000);
> +    }
> +
> +    scrn = hwp->readSeq(hwp, 0x01);
> +    scrn |= 0x20;/* blank screen */
> +    vgaHWSeqReset(hwp, TRUE);
> +    MGAWAITVSYNC();
> +    MGAWAITBUSY();
> +    hwp->writeSeq(hwp, 0x01, scrn);/* change mode */
> +    usleep(20000);
> +
> +    /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
> +    hwp->writeCrtc(hwp, 17, restore->CRTC[17] & ~0x80);
> +
> +    for (i = 0; i < restore->numCRTC; i++)
> +	hwp->writeCrtc(hwp, i, restore->CRTC[i]);
> +
> +    for (i = 0; i < restore->numGraphics; i++)
> +    hwp->writeGr(hwp, i, restore->Graphics[i]);
> +
> +    hwp->enablePalette(hwp);
> +    for (i = 0; i < restore->numAttribute; i++)
> +    hwp->writeAttr(hwp, i, restore->Attribute[i]);
> +    hwp->disablePalette(hwp);
> +
> +    MGAWAITVSYNC();
> +    MGAWAITBUSY();
> +	hwp->writeSeq(hwp, 1, restore->Sequencer[1]);
> +    usleep(20000);
> +}
> +
> +void
> +MGAG200SESaveMode(ScrnInfoPtr scrninfp, vgaRegPtr save)
> +{
> +    vgaHWPtr hwp = VGAHWPTR(scrninfp);
> +    int i;
> +
> +    save->MiscOutReg = hwp->readMiscOut(hwp);
> +    if (save->MiscOutReg & 0x01)
> +    hwp->IOBase = VGA_IOBASE_COLOR;
> +    else
> +    hwp->IOBase = VGA_IOBASE_MONO;
> +
> +    for (i = 0; i < save->numCRTC; i++) {
> +    save->CRTC[i] = hwp->readCrtc(hwp, i);
> +#ifdef DEBUG
> +    ErrorF("CRTC[0x%02x] = 0x%02x\n", i, save->CRTC[i]);
> +#endif
> +    }
> +
> +    hwp->enablePalette(hwp);
> +    for (i = 0; i < save->numAttribute; i++) {
> +    save->Attribute[i] = hwp->readAttr(hwp, i);
> +#ifdef DEBUG
> +    ErrorF("Attribute[0x%02x] = 0x%02x\n", i, save->Attribute[i]);
> +#endif
> +    }
> +    hwp->disablePalette(hwp);
> +
> +    for (i = 0; i < save->numGraphics; i++) {
> +    save->Graphics[i] = hwp->readGr(hwp, i);
> +#ifdef DEBUG
> +    ErrorF("Graphics[0x%02x] = 0x%02x\n", i, save->Graphics[i]);
> +#endif
> +    }
> +
> +    for (i = 1; i < save->numSequencer; i++) {
> +    save->Sequencer[i] = hwp->readSeq(hwp, i);
> +#ifdef DEBUG
> +    ErrorF("Sequencer[0x%02x] = 0x%02x\n", i, save->Sequencer[i]);
> +#endif
> +    }
> +}
> +
> +void
> +MGAG200SEHWProtect(ScrnInfoPtr pScrn, Bool on)
> +{
> +  vgaHWPtr hwp = VGAHWPTR(pScrn);
> +  MGAPtr pMga = MGAPTR(pScrn);
> +
> +  unsigned char tmp;
> +
> +  if (pScrn->vtSema) {
> +    if (on) {
> +      /*
> +       * Turn off screen and disable sequencer.
> +       */
> +      tmp = hwp->readSeq(hwp, 0x01);
> +
> +      vgaHWSeqReset(hwp, TRUE);         /* start synchronous reset */
> +      MGAWAITVSYNC();
> +      MGAWAITBUSY();
> +      hwp->writeSeq(hwp, 0x01, tmp | 0x20); /* disable the display */
> +      usleep(20000);
> +      hwp->enablePalette(hwp);
> +    } else {
> +      /*
> +       * Reenable sequencer, then turn on screen.
> +       */
> +
> +      tmp = hwp->readSeq(hwp, 0x01);
> +
> +      MGAWAITVSYNC();
> +      MGAWAITBUSY();
> +      hwp->writeSeq(hwp, 0x01, tmp & ~0x20);    /* reenable display */
> +      usleep(20000);
> +      vgaHWSeqReset(hwp, FALSE);        /* clear synchronousreset */
> +
> +      hwp->disablePalette(hwp);
> +    }
> +  }
> +}
>   
> ------------------------------------------------------------------------
>
> 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.
>   
> ------------------------------------------------------------------------
>
> _______________________________________________
> xorg mailing list
> xorg at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/xorg
>   




More information about the xorg mailing list