Esempio n. 1
0
USHORT usGetVbeModeNum(ScrnInfoPtr pScrn, DisplayModePtr mode)
{
    RDCRecPtr pRDC;
    MODE_PRIVATE *pModePrivate;
    USHORT usVESAModeNum;
    UCHAR  ucColorDepth = (UCHAR)(pScrn->bitsPerPixel);

    pRDC = RDCPTR(pScrn);
    pModePrivate = MODE_PRIVATE_PTR(mode);
    
    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, DefaultLevel, "==Enter usGetVbeModeNum()== \n");
    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, InfoLevel, "==Display Width=0x%x, Height=0x%x, Color Depth=0x%x==\n",
               mode->HDisplay,mode->VDisplay,pScrn->bitsPerPixel);


    switch (ucColorDepth)
    {
        case 8:
            usVESAModeNum = pModePrivate->Mode_ID_8bpp;
            break;

        case 16:
            usVESAModeNum = pModePrivate->Mode_ID_16bpp;
            break;

        case 32:
            usVESAModeNum = pModePrivate->Mode_ID_32bpp;
            break;
    }

    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, DefaultLevel, "==Exit usGetVbeModeNum() return VESA Mode = 0x%x==\n", usVESAModeNum);
    return usVESAModeNum;

}
static Bool radeon_kernel_mode_enabled(ScrnInfoPtr pScrn, struct pci_device *pci_dev)
{
    char *busIdString;
    int ret;

    if (!xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
		   "[KMS] No DRICreatePCIBusID symbol, no kernel modesetting.\n");
	return FALSE;
    }

    busIdString = DRICreatePCIBusID(pci_dev);
    ret = drmCheckModesettingSupported(busIdString);
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    if (ret) {
      if (xf86LoadKernelModule("radeonkms"))
        ret = drmCheckModesettingSupported(busIdString);
    }
#endif
    free(busIdString);
    if (ret) {
      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
		   "[KMS] drm report modesetting isn't supported.\n");
	return FALSE;
    }

    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
		   "[KMS] Kernel modesetting enabled.\n");
    return TRUE;
}
Esempio n. 3
0
/* Bind GART memory with "key" at "offset" */
Bool
xf86BindGARTMemory(int screenNum, int key, unsigned long offset)
{
	agp_bind_t bind;
	int pageOffset;

	if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
		return FALSE;

	if (offset % AGP_PAGE_SIZE != 0) {
		xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: "
		    "offset (0x%lx) is not page-aligned (%d)\n",
		    offset, AGP_PAGE_SIZE);
		return FALSE;
	}
	pageOffset = offset / AGP_PAGE_SIZE;

	xf86DrvMsgVerb(screenNum, X_INFO, 3,
	    "xf86BindGARTMemory: bind key %d at 0x%08lx "
	    "(pgoffset %d)\n", key, offset, pageOffset);

	bind.agpb_pgstart = pageOffset;
	bind.agpb_key = key;

	if (ioctl(gartFd, AGPIOC_BIND, &bind) != 0) {
		xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: "
		    "binding of gart memory with key %d\n"
		    "\tat offset 0x%lx failed (%s)\n",
		    key, offset, strerror(errno));
		return FALSE;
	}

	return TRUE;
}
Esempio n. 4
0
Bool
RDCSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
{
    RDCRecPtr pRDC;
    MODE_PRIVATE *pModePrivate;
    CBIOS_ARGUMENTS CBiosArguments;
    CBIOS_Extension CBiosExtension;
    USHORT usVESAMode;
    
    pRDC = RDCPTR(pScrn);
    pModePrivate = MODE_PRIVATE_PTR(mode);
    
    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, InternalLevel, "==Enter RDCSetMode()== \n");

    vRDCOpenKey(pScrn);
    bRDCRegInit(pScrn);

    CBiosExtension.pCBiosArguments = &CBiosArguments;
    CBiosExtension.IOAddress = (USHORT)(pRDC->RelocateIO);
    CBiosExtension.VideoVirtualAddress = (ULONG)(pRDC->FBVirtualAddr);

    
    CBiosArguments.reg.x.AX = OEMFunction;
    CBiosArguments.reg.x.BX = SetDisplay1RefreshRate;
    CBiosArguments.reg.lh.CL = pModePrivate->ucRRate_ID;
    CInt10(&CBiosExtension);

    usVESAMode = usGetVbeModeNum(pScrn, mode);
    
    
    CBiosArguments.reg.x.AX = VBESetMode;
    CBiosArguments.reg.x.BX = (0x4000 | usVESAMode);
    CInt10(&CBiosExtension);

    
    CBiosArguments.reg.x.AX = VBESetGetScanLineLength;
    CBiosArguments.reg.lh.BL = 0x00;
    CBiosArguments.reg.x.CX = (USHORT)(pScrn->displayWidth);
    CInt10(&CBiosExtension);

    

    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, InternalLevel, "==Exit RDCSetMode(), return true== \n");    
    return (TRUE);    
}
static struct mtrr_wc_region *
mtrr_cull_wc_region(int screenNum, unsigned long base, unsigned long size,
		      MessageType from)
{
	/* Some BIOS writers thought that setting wc over the mmio
	   region of a graphics devices was a good idea. Try to fix
	   it. */

	struct mtrr_gentry gent;
	struct mtrr_wc_region *wcreturn = NULL, *wcr;
	int count, ret=0;

	/* Linux 2.0 users should not get a warning without -verbose */
	if (!mtrr_open(2))
		return NULL;

	for (gent.regnum = 0; 
	     ioctl(mtrr_fd, MTRRIOC_GET_ENTRY, &gent) >= 0;
	     gent.regnum++) {
		if (gent.type != MTRR_TYPE_WRCOMB
		    || gent.base + gent.size <= base
		    || base + size <= gent.base)
			continue;

		/* Found an overlapping region. Delete it. */
		
		wcr = xalloc(sizeof(*wcr));
		if (!wcr)
			return NULL;
		wcr->sentry.base = gent.base;
		wcr->sentry.size = gent.size;
		wcr->sentry.type = MTRR_TYPE_WRCOMB;
		wcr->added = FALSE;
		
		count = 3;
		while (count-- && 
		       (ret = ioctl(mtrr_fd, MTRRIOC_KILL_ENTRY, &(wcr->sentry))) < 0);
		
		if (ret >= 0) {
			xf86DrvMsg(screenNum, from,
				   "Removed MMIO write-combining range "
				   "(0x%lx,0x%lx)\n",
				   (unsigned long) gent.base, (unsigned long) gent.size);
			wcr->next = wcreturn;
			wcreturn = wcr;
			gent.regnum--;
		} else {
			xfree(wcr);
			xf86DrvMsgVerb(screenNum, X_WARNING, 0,
				   "Failed to remove MMIO "
				   "write-combining range (0x%lx,0x%lx)\n",
				       gent.base, (unsigned long) gent.size);
		}
	}
	return wcreturn;
}
Esempio n. 6
0
/*
 * Note, the FORCE_LOW flag is currently not used or supported.
 */
static Bool
AllocateOverlay(ScrnInfoPtr pScrn, int flags)
{
   I830Ptr pI830 = I830PTR(pScrn);
   unsigned long size, alloced;
   Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
   int verbosity = dryrun ? 4 : 1;
   const char *s = dryrun ? "[dryrun] " : "";

   /* Clear overlay info */
   memset(&(pI830->OverlayMem), 0, sizeof(pI830->OverlayMem));
   pI830->OverlayMem.Key = -1;

   if (!pI830->XvEnabled)
      return TRUE;

   /*
    * The overlay register space needs a physical address in
    * system memory.  We get this from the agpgart module using
    * a special memory type.
    */

   size = OVERLAY_SIZE;
   if (flags & FORCE_LOW)
      flags |= FROM_POOL_ONLY | ALLOCATE_AT_BOTTOM | NEED_PHYSICAL_ADDR;
   else
      flags |= FROM_ANYWHERE | ALLOCATE_AT_TOP | NEED_PHYSICAL_ADDR;

   alloced = I830AllocVidMem(pScrn, &(pI830->OverlayMem),
			     &(pI830->StolenPool), size, GTT_PAGE_SIZE, flags);

   /*
    * XXX For testing only.  Don't enable this unless you know how to set
    * physBase.
    */
   if (flags & FORCE_LOW) {
      ErrorF("AllocateOverlay() doesn't support setting FORCE_LOW\n");
      return FALSE;
   }

   if (!dryrun && (alloced < size)) {
      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		 "Failed to allocate Overlay register space.\n");
	 /* This failure isn't fatal. */
   } else {
      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
		     "%sAllocated %d kB for Overlay registers at 0x%x "
		     "(0x%08x).\n", s,
		     alloced / 1024, pI830->OverlayMem.Start,
		     pI830->OverlayMem.Physical);
   }
   return TRUE;
}
static Bool
G80SorTMDSModeFixup(xf86OutputPtr output, DisplayModePtr mode,
                    DisplayModePtr adjusted_mode)
{
    int scrnIndex = output->scrn->scrnIndex;
    G80OutputPrivPtr pPriv = output->driver_private;
    DisplayModePtr modes = output->probed_modes;

    xf86DeleteMode(&pPriv->nativeMode, pPriv->nativeMode);

    if(modes) {
        // Find the preferred mode and use that as the "native" mode.
        // If no preferred mode is available, use the first one.
        DisplayModePtr mode;

        // Find the preferred mode.
        for(mode = modes; mode; mode = mode->next) {
            if(mode->type & M_T_PREFERRED) {
                xf86DrvMsgVerb(scrnIndex, X_INFO, 5,
                               "%s: preferred mode is %s\n",
                               output->name, mode->name);
                break;
            }
        }

        // XXX: May not want to allow scaling if no preferred mode is found.
        if(!mode) {
            mode = modes;
            xf86DrvMsgVerb(scrnIndex, X_INFO, 5,
                    "%s: no preferred mode found, using %s\n",
                    output->name, mode->name);
        }

        pPriv->nativeMode = xf86DuplicateMode(mode);
        G80CrtcDoModeFixup(pPriv->nativeMode, mode);
    }

    return G80SorModeFixup(output, mode, adjusted_mode);
}
Esempio n. 8
0
void
fbdevHWAdjustFrame(ScrnInfoPtr pScrn, int x, int y)
{
    fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);

    if (x < 0 || x + fPtr->var.xres > fPtr->var.xres_virtual ||
        y < 0 || y + fPtr->var.yres > fPtr->var.yres_virtual)
        return;

    fPtr->var.xoffset = x;
    fPtr->var.yoffset = y;
    if (-1 == ioctl(fPtr->fd, FBIOPAN_DISPLAY, (void *) &fPtr->var))
        xf86DrvMsgVerb(pScrn->scrnIndex, X_WARNING, 5,
                       "FBIOPAN_DISPLAY: %s\n", strerror(errno));
}
Esempio n. 9
0
void
fbdevHWAdjustFrame(int scrnIndex, int x, int y, int flags)
{
	ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
	fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);

	TRACE_ENTER("AdjustFrame");
	if ( x < 0 || x + fPtr->var.xres > fPtr->var.xres_virtual || 
	     y < 0 || y + fPtr->var.yres > fPtr->var.yres_virtual )
		return;

	fPtr->var.xoffset = x;
	fPtr->var.yoffset = y;
	if (-1 == ioctl(fPtr->fd,FBIOPAN_DISPLAY,(void*)&fPtr->var))
		xf86DrvMsgVerb(scrnIndex, X_WARNING, 5, 
			   "FBIOPAN_DISPLAY: %s\n", strerror(errno));
}
Esempio n. 10
0
static Bool radeon_ums_supported(ScrnInfoPtr pScrn, struct pci_device *pci_dev)
{
    unsigned family = 0, i;

    for (i = 0; i < sizeof(RADEONCards) / sizeof(RADEONCardInfo); i++) {
        if (pci_dev->device_id == RADEONCards[i].pci_device_id) {
            family = RADEONCards[i].chip_family;
            break;
        }
    }

    if (family >= CHIP_FAMILY_SUMO) {
        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
                       "GPU only supported with KMS, using vesa instead.\n");
        return FALSE;
    }
    return TRUE;
}
Esempio n. 11
0
int
I810CheckAvailableMemory(ScrnInfoPtr pScrn)
{
   AgpInfoPtr agpinf;
   int maxPages;

   if (!xf86AgpGARTSupported() ||
       !xf86AcquireGART(pScrn->scrnIndex) ||
       (agpinf = xf86GetAGPInfo(pScrn->scrnIndex)) == NULL ||
       !xf86ReleaseGART(pScrn->scrnIndex))
      return -1;

   maxPages = agpinf->totalPages - agpinf->usedPages;
   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "%s: %dk available\n",
		  "I810CheckAvailableMemory", maxPages * 4);

   return maxPages * 4;
}
Esempio n. 12
0
static Bool
AllocateRingBuffer(ScrnInfoPtr pScrn, int flags)
{
   I830Ptr pI830 = I830PTR(pScrn);
   unsigned long size, alloced;
   Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
   int verbosity = dryrun ? 4 : 1;
   const char *s = dryrun ? "[dryrun] " : "";

   /* Clear ring buffer  info */
   memset(&(pI830->LpRing), 0, sizeof(pI830->LpRing));
   pI830->LpRing.mem.Key = -1;

   if (pI830->noAccel)
      return TRUE;

   /* Ring buffer */
   size = PRIMARY_RINGBUFFER_SIZE;
   if (flags & FORCE_LOW)
      flags |= FROM_POOL_ONLY | ALLOCATE_AT_BOTTOM;
   else
      flags |= FROM_ANYWHERE | ALLOCATE_AT_TOP;

   alloced = I830AllocVidMem(pScrn, &(pI830->LpRing.mem),
				&(pI830->StolenPool), size,
				GTT_PAGE_SIZE, flags);
   if (alloced < size) {
      if (!dryrun) {
	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		    "Failed to allocate Ring Buffer space\n");
      }
      return FALSE;
   }
   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
		  "%sAllocated %d kB for the ring buffer at 0x%x\n", s,
		  alloced / 1024, pI830->LpRing.mem.Start);
   pI830->LpRing.tail_mask = pI830->LpRing.mem.Size - 1;
   return TRUE;
}
Esempio n. 13
0
/* Unbind GART memory with "key" */
Bool
xf86UnbindGARTMemory(int screenNum, int key)
{
	agp_unbind_t unbind;

	if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
		return FALSE;

	unbind.agpu_pri = 0;
	unbind.agpu_key = key;

	if (ioctl(gartFd, AGPIOC_UNBIND, &unbind) != 0) {
		xf86DrvMsg(screenNum, X_WARNING, "xf86UnbindGARTMemory: "
		    "unbinding of gart memory with key %d "
		    "failed (%s)\n", key, strerror(errno));
		return FALSE;
	}

	xf86DrvMsgVerb(screenNum, X_INFO, 3,
	    "xf86UnbindGARTMemory: unbind key %d\n", key);

	return TRUE;
}
Esempio n. 14
0
void
RHDOutputPrintSensedType(struct rhdOutput *Output)
{
    struct { enum rhdSensedOutput type; char *name; }
    list[] = { { RHD_SENSED_NONE, "none" },
	     { RHD_SENSED_VGA, "VGA" },
	     { RHD_SENSED_DVI, "DVI" },
	     { RHD_SENSED_TV_SVIDEO, "TV_SVIDEO"},
	     { RHD_SENSED_TV_COMPOSITE, "TV_COMPOSITE" },
	     { RHD_SENSED_TV_COMPONENT, "TV_COMPONENT" },
	     { 0, NULL }
    };
    int i = 0;

    while (list[i].name) {
	if (list[i].type == Output->SensedType) {
	    xf86DrvMsgVerb(Output->scrnIndex, X_INFO, 3,
			   "%s: Sensed Output: %s\n",Output->Name,
			   list[i].name);
	    return;
	}
	i++;
    }
}
static struct mtrr_wc_region *
mtrr_add_wc_region(int screenNum, unsigned long base, unsigned long size,
		   MessageType from)
{
        struct mtrr_wc_region **wcr, *wcreturn, *curwcr;

       /*
        * There can be only one....
        */

	wcreturn = mtrr_remove_offending(screenNum, base, size, from);
	wcr = &wcreturn;
	while (*wcr) {
	    wcr = &((*wcr)->next);
	} 

	/* Linux 2.0 should not warn, unless the user explicitly asks for
	   WC. */

	if (!mtrr_open(from == X_CONFIG ? 0 : 2))
		return wcreturn;

	*wcr = curwcr = xalloc(sizeof(**wcr));
	if (!curwcr)
	    return wcreturn;

	curwcr->sentry.base = base;
	curwcr->sentry.size = size;
	curwcr->sentry.type = MTRR_TYPE_WRCOMB;
	curwcr->added = TRUE;
	curwcr->next = NULL;

#if SPLIT_WC_REGIONS
	/*
	 * Splits up the write-combining region if it is not aligned on a
 	 * size boundary.
	 */

	{
	    unsigned long lbase, d_size = 1;
	    unsigned long n_size = size;
	    unsigned long n_base = base;

	    for (lbase = n_base, d_size = 1; !(lbase & 1);
		 lbase = lbase >> 1, d_size <<= 1);
	    while (d_size > n_size)
		d_size = d_size >> 1;
	    DebugF("WC_BASE: 0x%lx WC_END: 0x%lx\n",base,base+d_size-1);
	    n_base += d_size;
	    n_size -= d_size;
	    if (n_size) {
		xf86DrvMsgVerb(screenNum,X_INFO,3,"Splitting WC range: "
			       "base: 0x%lx, size: 0x%lx\n",base,size);
		curwcr->next = mtrr_add_wc_region(screenNum, n_base, n_size,from);
	    }
	    curwcr->sentry.size = d_size;
	} 
	
	/*****************************************************************/
#endif /* SPLIT_WC_REGIONS */

	if (ioctl(mtrr_fd, MTRRIOC_ADD_ENTRY, &curwcr->sentry) >= 0) {
		/* Avoid printing on every VT switch */
		if (xf86ServerIsInitialising()) {
			xf86DrvMsg(screenNum, from,
				   "Write-combining range (0x%lx,0x%lx)\n",
				   base, size);
		}
		return wcreturn;
	}
	else {
	        *wcr = curwcr->next;
		xfree(curwcr);
		
		/* Don't complain about the VGA region: MTRR fixed
		   regions aren't currently supported, but might be in
		   the future. */
		if ((unsigned long)base >= 0x100000) {
			xf86DrvMsgVerb(screenNum, X_WARNING, 0,
				"Failed to set up write-combining range "
				"(0x%lx,0x%lx)\n", base, size);
		}
		return wcreturn;
	}
}
Esempio n. 16
0
DisplayModePtr RDCBuildModePool(ScrnInfoPtr pScrn)
{
    DisplayModePtr pMode = NULL, pModePoolHead = NULL, pModePoolTail = NULL;
    
    CBIOS_ARGUMENTS CBiosArguments;
    CBIOS_Extension CBiosExtension;
    RDCRecPtr pRDC = RDCPTR(pScrn);
    MODE_PRIVATE *pModePrivate;
    USHORT usSerialNum = 0;
    USHORT wLCDHorSize, wLCDVerSize;
    USHORT wVESAModeHorSize, wVESAModeVerSize;
    BYTE bColorDepth; 

    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, DefaultLevel, "==Enter RDCBuildModePool()== \n");

    CBiosExtension.pCBiosArguments = &CBiosArguments;
    CBiosExtension.IOAddress = (USHORT)(pRDC->RelocateIO);
    CBiosExtension.VideoVirtualAddress = (ULONG)(pRDC->FBVirtualAddr);

    do {
        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 5, "Mode serial Num 0x%x\n",usSerialNum);

        CBiosArguments.reg.x.AX = OEMFunction;
        CBiosArguments.reg.x.BX = QuerySupportedMode;
        CBiosArguments.reg.x.CX = usSerialNum++;
        CInt10(&CBiosExtension);

        wVESAModeHorSize = (USHORT)(CBiosArguments.reg.ex.EDX & 0x0000FFFF);
        wVESAModeVerSize = (USHORT)(CBiosArguments.reg.ex.EDX >> 16);

        
        if (CBiosArguments.reg.x.AX == VBEFunctionCallSuccessful)
        {
            pMode = SearchDisplayModeRecPtr(pModePoolHead, CBiosArguments);

            if (pMode == NULL)
            {
                if (pModePoolHead != NULL)
                {
                    pModePoolTail->next = xnfcalloc(1, sizeof(DisplayModeRec));
                    pModePoolTail->next->prev = pModePoolTail;
                    pModePoolTail = pModePoolTail->next;
                }
                else
                {
                    pModePoolHead = xnfcalloc(1, sizeof(DisplayModeRec));
                    pModePoolHead->prev = NULL;
                    pModePoolTail = pModePoolHead;
                }
                
                pModePoolTail->next = NULL;

                pModePoolTail->name = pcConvertResolutionToString(CBiosArguments.reg.ex.EDX);

                pModePoolTail->status = MODE_OK;
                pModePoolTail->type = M_T_BUILTIN;
                pModePoolTail->Flags = 0;

                
                pModePoolTail->PrivSize = sizeof(MODE_PRIVATE);
                pModePoolTail->Private  = xnfcalloc(1, pModePoolTail->PrivSize);
                pModePrivate = MODE_PRIVATE_PTR(pModePoolTail);

                
                pModePoolTail->Clock = pModePoolTail->SynthClock = CBiosArguments.reg.ex.EDI;
                pModePoolTail->HDisplay = pModePoolTail->CrtcHDisplay = wVESAModeHorSize;
                pModePoolTail->VDisplay = pModePoolTail->CrtcVDisplay = wVESAModeVerSize;
                BTranslateIndexToRefreshRate(CBiosArguments.reg.lh.CH, &(pModePoolTail->VRefresh));
                
                pModePoolTail->PrivFlags = (int)CBiosArguments.reg.x.SI;
                pModePrivate->ucRRate_ID = CBiosArguments.reg.lh.CH;
            }
            else
            {
                pModePrivate = MODE_PRIVATE_PTR(pMode);
            }
            
            switch (CBiosArguments.reg.lh.CL)
            {
                case 8:
                    pModePrivate->Mode_ID_8bpp = CBiosArguments.reg.x.BX;
                    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 5, "pModePrivate->Mode_ID_8bpp = 0x%x\n",pModePrivate->Mode_ID_8bpp);
                    break;
                case 16:
                    pModePrivate->Mode_ID_16bpp = CBiosArguments.reg.x.BX;
                    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 5, "pModePrivate->Mode_ID_16bpp = 0x%x\n",pModePrivate->Mode_ID_16bpp);
                    break;
                case 32:
                    pModePrivate->Mode_ID_32bpp = CBiosArguments.reg.x.BX;
                    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 5, "pModePrivate->Mode_ID_32bpp = 0x%x\n",pModePrivate->Mode_ID_32bpp);
                    break;
            }
        }
    } while (CBiosArguments.reg.x.AX == VBEFunctionCallSuccessful);

    
        for (bColorDepth = 0; bColorDepth < 3; bColorDepth++)
        {
            CBiosArguments.reg.x.AX = OEMFunction;
            CBiosArguments.reg.x.BX = QueryLCDPanelSizeMode;
            CBiosArguments.reg.x.CX = bColorDepth;
            CInt10(&CBiosExtension);

            if (CBiosArguments.reg.x.AX == VBEFunctionCallSuccessful)
            {
                pMode = SearchDisplayModeRecPtr(pModePoolHead, CBiosArguments);

                if (pMode == NULL)
                {
                    if (pModePoolHead != NULL)
                    {
                        pModePoolTail->next = xnfcalloc(1, sizeof(DisplayModeRec));
                        pModePoolTail->next->prev = pModePoolTail;
                        pModePoolTail = pModePoolTail->next;
                    }
                    else
                    {
                        pModePoolHead = xnfcalloc(1, sizeof(DisplayModeRec));
                        pModePoolHead->prev = NULL;
                        pModePoolTail = pModePoolHead;
                    }
                    
                    pModePoolTail->next = NULL;

                    pModePoolTail->name = pcConvertResolutionToString(CBiosArguments.reg.ex.EDX);

                    pModePoolTail->status = MODE_OK;
                    pModePoolTail->type = M_T_BUILTIN;
                    pModePoolTail->Flags = 0;

                    
                    pModePoolTail->PrivSize = sizeof(MODE_PRIVATE);
                    pModePoolTail->Private  = xnfcalloc(1, pModePoolTail->PrivSize);
                    pModePrivate = MODE_PRIVATE_PTR(pModePoolTail);

                    
                    pModePoolTail->Clock = pModePoolTail->SynthClock = CBiosArguments.reg.ex.EDI;
                    pModePoolTail->HDisplay = pModePoolTail->CrtcHDisplay = (CBiosArguments.reg.ex.EDX & 0x0000FFFF);
                    pModePoolTail->VDisplay = pModePoolTail->CrtcVDisplay = (CBiosArguments.reg.ex.EDX >> 16);
                    BTranslateIndexToRefreshRate(CBiosArguments.reg.lh.CH, &(pModePoolTail->VRefresh));
                    
                    pModePoolTail->PrivFlags = (int)CBiosArguments.reg.x.SI | LCD_TIMING;
                    pModePrivate->ucRRate_ID = CBiosArguments.reg.lh.CH;
                }
                else
                {
                    pModePrivate = MODE_PRIVATE_PTR(pMode);
                }
                
                switch (CBiosArguments.reg.lh.CL)
                {
                    case 8:
                        pModePrivate->Mode_ID_8bpp = CBiosArguments.reg.x.BX;
                        break;
                    case 16:
                        pModePrivate->Mode_ID_16bpp = CBiosArguments.reg.x.BX;
                        break;
                    case 32:
                        pModePrivate->Mode_ID_32bpp = CBiosArguments.reg.x.BX;
                        break;
                }
                
            }
Esempio n. 17
0
File: xf86fbman.c Progetto: aosm/X11
Bool
xf86InitFBManagerArea(
    ScreenPtr pScreen,
    int PixelArea,
    int Verbosity
)
{
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    xRectangle Rect[3];
    RegionPtr pRegion, pScreenRegion;
    int nRect;
    Bool ret = FALSE;

    if (PixelArea < (pScrn->displayWidth * pScrn->virtualY))
	return FALSE;

    Rect[0].x = Rect[0].y = 0;
    Rect[0].width = pScrn->displayWidth;
    Rect[0].height = PixelArea / pScrn->displayWidth;
    nRect = 1;

    /* Add a possible partial scanline */
    if ((Rect[1].height = Rect[1].width = PixelArea % pScrn->displayWidth)) {
	Rect[1].x = 0;
	Rect[1].y = Rect[0].height;
	Rect[1].height = 1;
	nRect++;
    }

    /* Factor out virtual resolution */
    pRegion = RECTS_TO_REGION(pScreen, nRect, Rect, 0);
    if (pRegion) {
	if (!REGION_NAR(pRegion)) {
	    Rect[2].x = Rect[2].y = 0;
	    Rect[2].width = pScrn->virtualX;
	    Rect[2].height = pScrn->virtualY;

	    pScreenRegion = RECTS_TO_REGION(pScreen, 1, &Rect[2], 0);
	    if (pScreenRegion) {
		if (!REGION_NAR(pScreenRegion)) {
		    REGION_SUBTRACT(pScreen, pRegion, pRegion, pScreenRegion);

		    ret = xf86InitFBManagerRegion(pScreen, pRegion);

		    if (ret && xf86GetVerbosity() >= Verbosity) {
			int scrnIndex = pScrn->scrnIndex;

			xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
			    "Largest offscreen areas (with overlaps):\n");

			if (Rect[2].width < Rect[0].width) {
			    xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
				"\t%d x %d rectangle at %d,0\n",
				Rect[0].width - Rect[2].width,
				Rect[0].height,
				Rect[2].width);
			}
			if (Rect[2].width < Rect[1].width) {
			    xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
				"\t%d x %d rectangle at %d,0\n",
				Rect[1].width - Rect[2].width,
				Rect[0].height + Rect[1].height,
				Rect[2].width);
			}
			if (Rect[2].height < Rect[0].height) {
			    xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
				"\t%d x %d rectangle at 0,%d\n",
				Rect[0].width,
				Rect[0].height - Rect[2].height,
				Rect[2].height);
			}
			if (Rect[1].height) {
			    xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
				"\t%d x %d rectangle at 0,%d\n",
				Rect[1].width,
				Rect[0].height - Rect[2].height +
				    Rect[1].height,
				Rect[2].height);
			}
		    }
		}

		REGION_DESTROY(pScreen, pScreenRegion);
	    }
	}

	REGION_DESTROY(pScreen, pRegion);
    }

    return ret;
}
Esempio n. 18
0
Bool
I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags)
{
   I830Ptr pI830 = I830PTR(pScrn);
   unsigned long size, alloced, align = 0;
   int i;
   Bool tileable;
   Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
   int verbosity = dryrun ? 4 : 1;
   const char *s = dryrun ? "[dryrun] " : "";
   int lines;

   DPRINTF(PFX, "I830Allocate3DMemory\n");

   /* Back Buffer */
   memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer));
   pI830->BackBuffer.Key = -1;
   tileable = !(flags & ALLOC_NO_TILING) &&
	      IsTileable(pScrn->displayWidth * pI830->cpp);
   if (tileable) {
      /* Make the height a multiple of the tile height (16) */
      lines = (pScrn->virtualY + 15) / 16 * 16;
   } else {
      lines = pScrn->virtualY;
   }

   size = ROUND_TO_PAGE(pScrn->displayWidth * lines * pI830->cpp);
   /*
    * Try to allocate on the best tile-friendly boundaries.
    */
   alloced = 0;
   if (tileable) {
      align = GetBestTileAlignment(size);
      for (align = GetBestTileAlignment(size); align >= KB(512); align >>= 1) {
	 alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer),
				   &(pI830->StolenPool), size, align,
				   flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
				   ALIGN_BOTH_ENDS);
	 if (alloced >= size)
	    break;
      }
   }
   if (alloced < size) {
      /* Give up on trying to tile */
      tileable = FALSE;
      size = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * pI830->cpp);
      align = GTT_PAGE_SIZE;
      alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer),
				&(pI830->StolenPool), size, align,
				flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
   }
   if (alloced < size) {
      if (!dryrun) {
	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		    "Failed to allocate back buffer space.\n");
      }
      return FALSE;
   }
   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
		  "%sAllocated %d kB for the back buffer at 0x%x.\n", s,
		  alloced / 1024, pI830->BackBuffer.Start);

   /* Depth Buffer -- same size as the back buffer */
   memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer));
   pI830->DepthBuffer.Key = -1;
   /*
    * Try to allocate on the best tile-friendly boundaries.
    */
   alloced = 0;
   if (tileable) {
      /* Start with the previous align value. */
      for (; align >= KB(512); align >>= 1) {
	 alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer),
				   &(pI830->StolenPool), size, align,
				   flags | FROM_ANYWHERE | ALLOCATE_AT_TOP |
				   ALIGN_BOTH_ENDS);
	 if (alloced >= size)
	    break;
      }
   }
   if (alloced < size) {
      /* Give up on trying to tile */
      tileable = FALSE;
      size = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * pI830->cpp);
      align = GTT_PAGE_SIZE;
      alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer),
				&(pI830->StolenPool), size, align,
				flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
   }
   if (alloced < size) {
      if (!dryrun) {
	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		    "Failed to allocate depth buffer space.\n");
      }
      return FALSE;
   }
   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
		  "%sAllocated %d kB for the depth buffer at 0x%x.\n", s,
		  alloced / 1024, pI830->DepthBuffer.Start);

   /* Space for logical context.  32k is fine for right now. */
   memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem));
   pI830->ContextMem.Key = -1;
   size = KB(32);
   alloced = I830AllocVidMem(pScrn, &(pI830->ContextMem),
			     &(pI830->StolenPool), size, GTT_PAGE_SIZE,
			     flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
   if (alloced < size) {
      if (!dryrun) {
	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		    "Failed to allocate logical context space.\n");
      }
      return FALSE;
   }
   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
		  "%sAllocated %d kB for the logical context at 0x%x.\n", s,
		  alloced / 1024, pI830->ContextMem.Start);

   /*
    * Space for DMA buffers, only if there's enough free for at least 1MB
    * of texture space.
    */
   memset(&(pI830->BufferMem), 0, sizeof(pI830->BufferMem));
   pI830->BufferMem.Key = -1;
   /* This should already be a page multiple */
   size = I830_DMA_BUF_NR * I830_DMA_BUF_SZ;
   if (dryrun || (GetFreeSpace(pScrn) >= size + MB(1))) {
      alloced = I830AllocVidMem(pScrn, &(pI830->BufferMem),
				&(pI830->StolenPool), size,
				GTT_PAGE_SIZE,
				flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
      if (alloced < size) {
	 if (!dryrun) {
	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		       "Failed to allocate DMA buffer space.\n");
	 }
	 return FALSE;
      }
      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
		     "%sAllocated %d kB for the DMA buffers at 0x%x.\n", s,
		     alloced / 1024, pI830->BufferMem.Start);
   } else {
      if (!dryrun) {
	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		    "Not enough free space for DMA buffers.\n");
      }
      return FALSE;
   }

   /* Allocate the remaining space for textures. */
   memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem));
   pI830->TexMem.Key = -1;
   size = GetFreeSpace(pScrn);
   if (dryrun && (size < MB(1)))
      size = MB(1);
   i = myLog2(size / I830_NR_TEX_REGIONS);
   if (i < I830_LOG_MIN_TEX_REGION_SIZE)
      i = I830_LOG_MIN_TEX_REGION_SIZE;
   pI830->TexGranularity = i;
   /* Truncate size */
   size >>= i;
   size <<= i;
   if (size < KB(512)) {
      if (!dryrun) {
	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		    "Less than %d kBytes for texture space.\n", size / 1024);
      }
      return FALSE;
   }
   alloced = I830AllocVidMem(pScrn, &(pI830->TexMem),
			     &(pI830->StolenPool), size, GTT_PAGE_SIZE,
			     flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
   if (alloced < size) {
      if (!dryrun) {
	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		    "Failed to allocate texture space.\n");
      }
      return FALSE;
   }
   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
		  "%sAllocated %d kB for textures at 0x%x\n", s,
		  alloced / 1024, pI830->TexMem.Start);

   return TRUE;
}
Esempio n. 19
0
Bool
I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
{
   I830Ptr pI830 = I830PTR(pScrn);
   unsigned long size, alloced;
   Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
   int verbosity = dryrun ? 4 : 1;
   const char *s = dryrun ? "[dryrun] " : "";
   Bool tileable;
   int align, alignflags;

   DPRINTF(PFX, "I830Allocate2DMemory: inital is %s\n",
	   BOOLTOSTRING(flags & ALLOC_INITIAL));

   if (!pI830->StolenOnly &&
       (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) {
      if (!dryrun) {
	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		    "AGP GART support is either not available or cannot "
		    "be used.\n"
		    "\tMake sure your kernel has agpgart support or has the\n"
		    "\tagpgart module loaded.\n");
      }
      return FALSE;
   }


   /*
    * The I830 is slightly different from the I830/I815, it has no
    * dcache and it has stolen memory by default in its gtt.  All
    * additional memory must go after it.
    */

   DPRINTF(PFX,
	   "size == %luk (%lu bytes == pScrn->videoRam)\n"
	   "pI830->StolenSize == %luk (%lu bytes)\n",
	   pScrn->videoRam, pScrn->videoRam * 1024,
	   pI830->StolenPool.Free.Size / 1024,
	   pI830->StolenPool.Free.Size);

   if (flags & ALLOC_INITIAL) {
      unsigned long minspace, avail, lineSize;
      int cacheLines, maxCacheLines;

      if (pI830->NeedRingBufferLow)
	 AllocateRingBuffer(pScrn, flags | FORCE_LOW);

      /* Clear everything first. */
      memset(&(pI830->FbMemBox), 0, sizeof(pI830->FbMemBox));
      memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer));
      pI830->FrontBuffer.Key = -1;

      pI830->FbMemBox.x1 = 0;
      pI830->FbMemBox.x2 = pScrn->displayWidth;
      pI830->FbMemBox.y1 = 0;
      pI830->FbMemBox.y2 = pScrn->virtualY;

      /*
       * Calculate how much framebuffer memory to allocate.  For the
       * initial allocation, calculate a reasonable minimum.  This is
       * enough for the virtual screen size, plus some pixmap cache
       * space.
       */

      lineSize = pScrn->displayWidth * pI830->cpp;
      minspace = lineSize * pScrn->virtualY;
      avail = pScrn->videoRam * 1024;
      maxCacheLines = (avail - minspace) / lineSize;
      /* This shouldn't happen. */
      if (maxCacheLines < 0) {
	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		    "Internal Error: "
		    "maxCacheLines < 0 in I830Allocate2DMemory()\n");
	 maxCacheLines = 0;
      }
      if (maxCacheLines > (MAX_DISPLAY_HEIGHT - pScrn->virtualY))
	 maxCacheLines = MAX_DISPLAY_HEIGHT - pScrn->virtualY;

      if (pI830->CacheLines >= 0) {
	 cacheLines = pI830->CacheLines;
      } else {
#if 1
	 /* Make sure there is enough for two DVD sized YUV buffers */
	 cacheLines = (pScrn->depth == 24) ? 256 : 384;
	 if (pScrn->displayWidth <= 1024)
	    cacheLines *= 2;
#else
	 /*
	  * Make sure there is enough for two DVD sized YUV buffers.
	  * Make that 1.5MB, which is around what was allocated with
	  * the old algorithm
	  */
	 cacheLines = (MB(1) + KB(512)) / pI830->cpp / pScrn->displayWidth;
#endif
      }
      if (cacheLines > maxCacheLines)
	 cacheLines = maxCacheLines;

      pI830->FbMemBox.y2 += cacheLines;

      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
		     "%sAllocating at least %d scanlines for pixmap cache\n",
		     s, cacheLines);

      tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip &&
		 IsTileable(pScrn->displayWidth * pI830->cpp);
      if (tileable) {
	 align = KB(512);
	 alignflags = ALIGN_BOTH_ENDS;
      } else {
	 align = KB(64);
	 alignflags = 0;
      }

      size = lineSize * (pScrn->virtualY + cacheLines);
      size = ROUND_TO_PAGE(size);
      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
		     "%sInitial framebuffer allocation size: %d kByte\n", s,
		     size / 1024);
      alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer),
				&(pI830->StolenPool), size, align,
				flags | alignflags |
				FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
      if (alloced < size) {
	 if (!dryrun) {
	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		       "Failed to allocate framebuffer.\n");
	 }
	 return FALSE;
      }
   } else {
      unsigned long lineSize;
      unsigned long extra = 0;
      unsigned long maxFb = 0;

      /*
       * XXX Need to "free" up any 3D allocations if the DRI ended up
       * and make them available for 2D.  The best way to do this would
       * be position all of those regions contiguously at the end of the
       * StolenPool.
       */
      extra = GetFreeSpace(pScrn);

      if (extra == 0)
	 return TRUE;

      maxFb = pI830->FrontBuffer.Size + extra;
      lineSize = pScrn->displayWidth * pI830->cpp;
      maxFb = ROUND_DOWN_TO(maxFb, lineSize);
      if (maxFb > lineSize * MAX_DISPLAY_HEIGHT)
	 maxFb = lineSize * MAX_DISPLAY_HEIGHT;
      if (maxFb > pI830->FrontBuffer.Size) {
	 unsigned long oldsize;
	 /*
	  * Sanity check -- the fb should be the last thing allocated at
	  * the bottom of the stolen pool.
	  */
	 if (pI830->StolenPool.Free.Start != pI830->FrontBuffer.End) {
	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		       "Internal error in I830Allocate2DMemory():\n\t"
		       "Framebuffer isn't the last allocation at the bottom"
		       " of StolenPool\n\t(%x != %x).\n",
		       pI830->FrontBuffer.End,
		       pI830->StolenPool.Free.Start);
	    return FALSE;
	 }
	 /*
	  * XXX Maybe should have a "Free" function.  This should be
	  * the only place where a region is resized, and we know that
	  * the fb is always at the bottom of the aperture/stolen pool,
	  * and is the only region that is allocated bottom-up.
	  * Allowing for more general realloction would require a smarter
	  * allocation system.
	  */
	 oldsize = pI830->FrontBuffer.Size;
	 pI830->StolenPool.Free.Size += pI830->FrontBuffer.Size;
	 pI830->StolenPool.Free.Start -= pI830->FrontBuffer.Size;
	 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
			"%sUpdated framebuffer allocation size from %d "
			"to %d kByte\n", s, oldsize / 1024, maxFb / 1024);
	 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
			"%sUpdated pixmap cache from %d scanlines to %d "
			"scanlines\n", s,
			oldsize / lineSize - pScrn->virtualY,
			maxFb / lineSize - pScrn->virtualY);
	 pI830->FbMemBox.y2 = maxFb / lineSize;
	 tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip &&
		 IsTileable(pScrn->displayWidth * pI830->cpp);
	 if (tileable) {
	    align = KB(512);
	    alignflags = ALIGN_BOTH_ENDS;
	 } else {
	    align = KB(64);
	    alignflags = 0;
	 }
	 alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer),
				   &(pI830->StolenPool), maxFb, align,
				   flags | alignflags |
				   FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
	 if (alloced < maxFb) {
	    if (!dryrun) {
	       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
			  "Failed to re-allocate framebuffer\n");
	    }
	    return FALSE;
	 }
      }
      return TRUE;
   }

#if REMAP_RESERVED
   /*
    * Allocate a dummy page to pass when attempting to rebind the
    * pre-allocated region.
    */
   if (!dryrun) {
      memset(&(pI830->Dummy), 0, sizeof(pI830->Dummy));
      pI830->Dummy.Key =
	   xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
      pI830->Dummy.Offset = 0;
   }
#endif

   /* Clear cursor info */
   memset(&(pI830->CursorMem), 0, sizeof(pI830->CursorMem));
   pI830->CursorMem.Key = -1;

   if (!pI830->SWCursor) {
      int cursFlags = 0;
      /*
       * Mouse cursor -- The i810-i830 need a physical address in system
       * memory from which to upload the cursor.  We get this from
       * the agpgart module using a special memory type.
       */

      size = HWCURSOR_SIZE;
      cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP;
      if (pI830->CursorNeedsPhysical)
	 cursFlags |= NEED_PHYSICAL_ADDR;

      alloced = I830AllocVidMem(pScrn, &(pI830->CursorMem),
				&(pI830->StolenPool), size,
				GTT_PAGE_SIZE, flags | cursFlags);
      if (alloced < size) {
	 if (!dryrun) {
	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		       "Failed to allocate HW cursor space.\n");
	 }
      } else {
	 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
			"%sAllocated %d kB for HW cursor at 0x%x", s,
			alloced / 1024, pI830->CursorMem.Start);
	 if (pI830->CursorNeedsPhysical)
	    xf86ErrorFVerb(verbosity, " (0x%08x)", pI830->CursorMem.Physical);
	 xf86ErrorFVerb(verbosity, "\n");
      }
   }

#ifdef I830_XV
   AllocateOverlay(pScrn, flags);
#endif

   if (!pI830->NeedRingBufferLow)
      AllocateRingBuffer(pScrn, flags);

   /* Clear scratch info */
   memset(&(pI830->Scratch), 0, sizeof(pI830->Scratch));
   pI830->Scratch.Key = -1;

   if (!pI830->noAccel) {
      size = MAX_SCRATCH_BUFFER_SIZE;
      alloced = I830AllocVidMem(pScrn, &(pI830->Scratch), &(pI830->StolenPool),
				size, GTT_PAGE_SIZE,
				flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
      if (alloced < size) {
	 size = MIN_SCRATCH_BUFFER_SIZE;
         alloced = I830AllocVidMem(pScrn, &(pI830->Scratch),
				   &(pI830->StolenPool), size,
				   GTT_PAGE_SIZE,
				   flags | FROM_ANYWHERE | ALLOCATE_AT_TOP);
      }
      if (alloced < size) {
	 if (!dryrun) {
	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		       "Failed to allocate scratch buffer space\n");
	 }
	 return FALSE;
      }
      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
		    "%sAllocated %d kB for the scratch buffer at 0x%x\n", s,
		    alloced / 1024, pI830->Scratch.Start);
   }
   return TRUE;
}
Esempio n. 20
0
void
SMILynx_Save(ScrnInfoPtr pScrn)
{
    SMIPtr	pSmi = SMIPTR(pScrn);
    int		i;
    CARD32	offset;
    SMIRegPtr	save = pSmi->save;
    vgaHWPtr	hwp = VGAHWPTR(pScrn);
    vgaRegPtr	vgaSavePtr = &hwp->SavedReg;
    int		vgaIOBase  = hwp->IOBase;
    int		vgaCRIndex = vgaIOBase + VGA_CRTC_INDEX_OFFSET;
    int		vgaCRData  = vgaIOBase + VGA_CRTC_DATA_OFFSET;

    ENTER();

    /* Save the standard VGA registers */
    vgaHWSave(pScrn, vgaSavePtr, VGA_SR_ALL);
    save->smiDACMask = VGAIN8(pSmi, VGA_DAC_MASK);
    VGAOUT8(pSmi, VGA_DAC_READ_ADDR, 0);
    for (i = 0; i < 256; i++) {
	save->smiDacRegs[i][0] = VGAIN8(pSmi, VGA_DAC_DATA);
	save->smiDacRegs[i][1] = VGAIN8(pSmi, VGA_DAC_DATA);
	save->smiDacRegs[i][2] = VGAIN8(pSmi, VGA_DAC_DATA);
    }
    for (i = 0, offset = 2; i < 8192; i++, offset += 8)
	save->smiFont[i] = *(pSmi->FBBase + offset);

    /* Now we save all the extended registers we need. */
    save->SR17 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x17);
    save->SR18 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x18);

    save->SR20 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20);
    save->SR21 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21);
    save->SR22 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22);
    save->SR23 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x23);
    save->SR24 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x24);

    save->SR31 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31);
    save->SR32 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x32);

    save->SR66 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66);
    save->SR68 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x68);
    save->SR69 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x69);
    save->SR6A = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A);
    save->SR6B = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B);
    save->SR6C = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6C);
    save->SR6D = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6D);

    save->SR81 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81);
    save->SRA0 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0xA0);

    if (pSmi->Dualhead) {
	/* dualhead stuff */
	save->SR40 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x40);
	save->SR41 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x41);
	save->SR42 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x42);
	save->SR43 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x43);
	save->SR44 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x44);
	save->SR45 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x45);
	save->SR48 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x48);
	save->SR49 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x49);
	save->SR4A = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4A);
	save->SR4B = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4B);
	save->SR4C = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4C);

	save->SR50 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x50);
	save->SR51 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x51);
	save->SR52 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x52);
	save->SR53 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x53);
	save->SR54 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x54);
	save->SR55 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x55);
	save->SR56 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x56);
	save->SR57 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x57);
	save->SR5A = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x5A);

	/* PLL2 stuff */
	save->SR6E = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6E);
	save->SR6F = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6F);
    }

    if (SMI_LYNXM_SERIES(pSmi->Chipset)) {
	/* Save common registers */
	save->CR30 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x30);
	save->CR3A = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A);
	for (i = 0; i < 15; i++) {
	    save->CR90[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x90 + i);
	}
	for (i = 0; i < 14; i++) {
	    save->CRA0[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0xA0 + i);
	}

	/* Save primary registers */
	VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, save->CR90[14] & ~0x20);

	save->CR33 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33);
	for (i = 0; i < 14; i++) {
	    save->CR40[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i);
	}
	save->CR9F = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9F);

	/* Save secondary registers */
	VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, save->CR90[14] | 0x20);
	save->CR33_2 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33);
	for (i = 0; i < 14; i++) {
	    save->CR40_2[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i);
	}
	save->CR9F_2 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9F);

	/* PDR#1069 */
	VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E, save->CR90[14]);

    }
    else {
	save->CR30 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x30);
	save->CR33 = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33);
	save->CR3A = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A);
	for (i = 0; i < 14; i++) {
	    save->CR40[i] = VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i);
	}
    }

    save->DPR10 = READ_DPR(pSmi, 0x10);
    save->DPR1C = READ_DPR(pSmi, 0x1C);
    save->DPR20 = READ_DPR(pSmi, 0x20);
    save->DPR24 = READ_DPR(pSmi, 0x24);
    save->DPR28 = READ_DPR(pSmi, 0x28);
    save->DPR2C = READ_DPR(pSmi, 0x2C);
    save->DPR30 = READ_DPR(pSmi, 0x30);
    save->DPR3C = READ_DPR(pSmi, 0x3C);
    save->DPR40 = READ_DPR(pSmi, 0x40);
    save->DPR44 = READ_DPR(pSmi, 0x44);

    save->VPR00 = READ_VPR(pSmi, 0x00);
    save->VPR0C = READ_VPR(pSmi, 0x0C);
    save->VPR10 = READ_VPR(pSmi, 0x10);

    if (pSmi->Chipset == SMI_COUGAR3DR) {
	save->FPR00_ = READ_FPR(pSmi, FPR00);
	save->FPR0C_ = READ_FPR(pSmi, FPR0C);
	save->FPR10_ = READ_FPR(pSmi, FPR10);
    }

    save->CPR00 = READ_CPR(pSmi, 0x00);

    if (!pSmi->ModeStructInit) {
	vgaHWCopyReg(&hwp->ModeReg, vgaSavePtr);
	memcpy(pSmi->mode, save, sizeof(SMIRegRec));
	pSmi->ModeStructInit = TRUE;
    }

    if (pSmi->useBIOS && pSmi->pInt10 != NULL) {
	pSmi->pInt10->num = 0x10;
	pSmi->pInt10->ax = 0x0F00;
	xf86ExecX86int10(pSmi->pInt10);
	save->mode = pSmi->pInt10->ax & 0x007F;
	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Current mode 0x%02X.\n",
		   save->mode);
    }

    if (xf86GetVerbosity() > 1) {
	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV,
		       "Saved current video mode.  Register dump:\n");
	SMI_PrintRegs(pScrn);
    }

    LEAVE();
}
Esempio n. 21
0
/*
 * ATIDSPPreInit --
 *
 * This function initialises global variables used to set DSP registers on a
 * VT-B or later.
 */
Bool
ATIDSPPreInit
(
    int    iScreen,
    ATIPtr pATI
)
{
    CARD32 IOValue, dsp_config, dsp_on_off, vga_dsp_config, vga_dsp_on_off;
    int trp;

    /*
     * VT-B's and later have additional post-dividers that are not powers of
     * two.
     */
    pATI->ClockDescriptor.NumD = 8;

    /* Retrieve XCLK settings */
    IOValue = ATIGetMach64PLLReg(PLL_XCLK_CNTL);
    pATI->XCLKPostDivider = GetBits(IOValue, PLL_XCLK_SRC_SEL);
    pATI->XCLKReferenceDivider = 1;
    switch (pATI->XCLKPostDivider)
    {
        case 0:  case 1:  case 2:  case 3:
            break;

        case 4:
            pATI->XCLKReferenceDivider = 3;
            pATI->XCLKPostDivider = 0;
            break;

        default:
            xf86DrvMsg(iScreen, X_ERROR,
                "Unsupported XCLK source:  %d.\n", pATI->XCLKPostDivider);
            return FALSE;
    }

    pATI->XCLKPostDivider -= GetBits(IOValue, PLL_MFB_TIMES_4_2B);
    pATI->XCLKFeedbackDivider = ATIGetMach64PLLReg(PLL_MCLK_FB_DIV);

    xf86DrvMsgVerb(iScreen, X_INFO, 2,
        "Engine XCLK %.3f MHz;  Refresh rate code %d.\n",
        ATIDivide(pATI->XCLKFeedbackDivider * pATI->ReferenceNumerator,
                  pATI->XCLKReferenceDivider * pATI->ClockDescriptor.MaxM *
                  pATI->ReferenceDenominator, 1 - pATI->XCLKPostDivider, 0) /
        (double)1000.0,
        GetBits(pATI->LockData.mem_cntl, CTL_MEM_REFRESH_RATE_B));

    /* Compute maximum RAS delay and friends */
    trp = GetBits(pATI->LockData.mem_cntl, CTL_MEM_TRP);
    pATI->XCLKPageFaultDelay = GetBits(pATI->LockData.mem_cntl, CTL_MEM_TRCD) +
        GetBits(pATI->LockData.mem_cntl, CTL_MEM_TCRD) + trp + 2;
    pATI->XCLKMaxRASDelay = GetBits(pATI->LockData.mem_cntl, CTL_MEM_TRAS) +
        trp + 2;
    pATI->DisplayFIFODepth = 32;

    if (pATI->Chip < ATI_CHIP_264VT4)
    {
        pATI->XCLKPageFaultDelay += 2;
        pATI->XCLKMaxRASDelay += 3;
        pATI->DisplayFIFODepth = 24;
    }

    switch (pATI->MemoryType)
    {
        case MEM_264_DRAM:
            if (pATI->VideoRAM <= 1024)
                pATI->DisplayLoopLatency = 10;
            else
            {
                pATI->DisplayLoopLatency = 8;
                pATI->XCLKPageFaultDelay += 2;
            }
            break;

        case MEM_264_EDO:
        case MEM_264_PSEUDO_EDO:
            if (pATI->VideoRAM <= 1024)
                pATI->DisplayLoopLatency = 9;
            else
            {
                pATI->DisplayLoopLatency = 8;
                pATI->XCLKPageFaultDelay++;
            }
            break;

        case MEM_264_SDRAM:
            if (pATI->VideoRAM <= 1024)
                pATI->DisplayLoopLatency = 11;
            else
            {
                pATI->DisplayLoopLatency = 10;
                pATI->XCLKPageFaultDelay++;
            }
            break;

        case MEM_264_SGRAM:
            pATI->DisplayLoopLatency = 8;
            pATI->XCLKPageFaultDelay += 3;
            break;

        default:                /* Set maximums */
            pATI->DisplayLoopLatency = 11;
            pATI->XCLKPageFaultDelay += 3;
            break;
    }

    if (pATI->XCLKMaxRASDelay <= pATI->XCLKPageFaultDelay)
        pATI->XCLKMaxRASDelay = pATI->XCLKPageFaultDelay + 1;

    /* Allow BIOS to override */
    dsp_config = inr(DSP_CONFIG);
    dsp_on_off = inr(DSP_ON_OFF);
    vga_dsp_config = inr(VGA_DSP_CONFIG);
    vga_dsp_on_off = inr(VGA_DSP_ON_OFF);

    if (dsp_config)
        pATI->DisplayLoopLatency = GetBits(dsp_config, DSP_LOOP_LATENCY);

    if ((!dsp_on_off && (pATI->Chip < ATI_CHIP_264GTPRO)) ||
        ((dsp_on_off == vga_dsp_on_off) &&
         (!dsp_config || !((dsp_config ^ vga_dsp_config) & DSP_XCLKS_PER_QW))))
    {
        if (ATIDivide(GetBits(vga_dsp_on_off, VGA_DSP_OFF),
                      GetBits(vga_dsp_config, VGA_DSP_XCLKS_PER_QW), 5, 1) > 24)
            pATI->DisplayFIFODepth = 32;
        else
            pATI->DisplayFIFODepth = 24;
    }

    return TRUE;
}
Esempio n. 22
0
Bool
xf86DeallocateGARTMemory(int screenNum, int key)
{
	if (!GARTInit(screenNum) || acquiredScreen != screenNum)
		return FALSE;

	if (acquiredScreen != screenNum) {
		xf86DrvMsg(screenNum, X_ERROR,
                   "xf86UnbindGARTMemory: AGP not acquired by this screen\n");
		return FALSE;
	}

#ifdef __linux__
	if (ioctl(gartFd, AGPIOC_DEALLOCATE, (int *)(uintptr_t)key) != 0) {
#else
	if (ioctl(gartFd, AGPIOC_DEALLOCATE, &key) != 0) {
#endif
		xf86DrvMsg(screenNum, X_WARNING,"xf86DeAllocateGARTMemory: "
                   "deallocation gart memory with key %d failed\n\t(%s)\n",
                   key, strerror(errno));
		return FALSE;
	}

	return TRUE;
}

/* Bind GART memory with "key" at "offset" */
Bool
xf86BindGARTMemory(int screenNum, int key, unsigned long offset)
{
	struct _agp_bind bind;
	int pageOffset;

	if (!GARTInit(screenNum) || acquiredScreen != screenNum)
		return FALSE;

	if (acquiredScreen != screenNum) {
		xf86DrvMsg(screenNum, X_ERROR,
		      "xf86BindGARTMemory: AGP not acquired by this screen\n");
		return FALSE;
	}

	if (offset % AGP_PAGE_SIZE != 0) {
		xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: "
			   "offset (0x%lx) is not page-aligned (%d)\n",
			   offset, AGP_PAGE_SIZE);
		return FALSE;
	}
	pageOffset = offset / AGP_PAGE_SIZE;

	xf86DrvMsgVerb(screenNum, X_INFO, 3,
		       "xf86BindGARTMemory: bind key %d at 0x%08lx "
		       "(pgoffset %d)\n", key, offset, pageOffset);

	bind.pg_start = pageOffset;
	bind.key = key;

	if (ioctl(gartFd, AGPIOC_BIND, &bind) != 0) {
		xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: "
			   "binding of gart memory with key %d\n"
			   "\tat offset 0x%lx failed (%s)\n",
			   key, offset, strerror(errno));
		return FALSE;
	}

	return TRUE;
}


/* Unbind GART memory with "key" */
Bool
xf86UnbindGARTMemory(int screenNum, int key)
{
	struct _agp_unbind unbind;

	if (!GARTInit(screenNum) || acquiredScreen != screenNum)
		return FALSE;

	if (acquiredScreen != screenNum) {
		xf86DrvMsg(screenNum, X_ERROR,
		    "xf86UnbindGARTMemory: AGP not acquired by this screen\n");
		return FALSE;
	}

	unbind.priority = 0;
	unbind.key = key;

	if (ioctl(gartFd, AGPIOC_UNBIND, &unbind) != 0) {
		xf86DrvMsg(screenNum, X_WARNING, "xf86UnbindGARTMemory: "
			   "unbinding of gart memory with key %d "
			   "failed (%s)\n", key, strerror(errno));
		return FALSE;
	}

	xf86DrvMsgVerb(screenNum, X_INFO, 3,
		       "xf86UnbindGARTMemory: unbind key %d\n", key);

	return TRUE;
}


/* XXX Interface may change. */
Bool
xf86EnableAGP(int screenNum, CARD32 mode)
{
	agp_setup setup;

	if (!GARTInit(screenNum) || acquiredScreen != screenNum)
		return FALSE;

	setup.agp_mode = mode;
	if (ioctl(gartFd, AGPIOC_SETUP, &setup) != 0) {
		xf86DrvMsg(screenNum, X_WARNING, "xf86EnableAGP: "
			   "AGPIOC_SETUP with mode %ld failed (%s)\n",
			   (unsigned long)mode, strerror(errno));
		return FALSE;
	}

	return TRUE;
}
Esempio n. 23
0
void
SMILynx_WriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, SMIRegPtr restore)
{
    SMIPtr	pSmi = SMIPTR(pScrn);
    int		i;
    CARD8	tmp;
    CARD32	offset;
    vgaHWPtr	hwp = VGAHWPTR(pScrn);
    int		vgaIOBase  = hwp->IOBase;
    int		vgaCRIndex = vgaIOBase + VGA_CRTC_INDEX_OFFSET;
    int		vgaCRData  = vgaIOBase + VGA_CRTC_DATA_OFFSET;

    ENTER();

    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x17, restore->SR17);
    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x18, restore->SR18);

    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x20, restore->SR20);
    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, restore->SR21);
    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x22, restore->SR22);
    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x23, restore->SR23);
    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x24, restore->SR24);

    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x31, restore->SR31);
    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x32, restore->SR32);

    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x66, restore->SR66);
    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x68, restore->SR68);
    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x69, restore->SR69);
    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6A, restore->SR6A);
    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6B, restore->SR6B);
    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6C, restore->SR6C);
    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6D, restore->SR6D);

    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x81, restore->SR81);
    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0xA0, restore->SRA0);

    if (pSmi->useBIOS && restore->mode != 0){
	pSmi->pInt10->num = 0x10;
	pSmi->pInt10->ax = restore->mode | 0x80;
	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting mode 0x%02X\n",
		   restore->mode);
	xf86ExecX86int10(pSmi->pInt10);

	/* Enable linear mode. */
	outb(pSmi->PIOBase + VGA_SEQ_INDEX, 0x18);
	tmp = inb(pSmi->PIOBase + VGA_SEQ_DATA);
	outb(pSmi->PIOBase + VGA_SEQ_DATA, tmp | 0x01);

	/* Enable DPR/VPR registers. */
	tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21);
	VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x21, tmp & ~0x03);
    } else {
	/* Restore the standard VGA registers */
	vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_ALL);
	if (restore->smiDACMask) {
	    VGAOUT8(pSmi, VGA_DAC_MASK, restore->smiDACMask);
	} else {
	    VGAOUT8(pSmi, VGA_DAC_MASK, 0xFF);
	}
	VGAOUT8(pSmi, VGA_DAC_WRITE_ADDR, 0);
	for (i = 0; i < 256; i++) {
	    VGAOUT8(pSmi, VGA_DAC_DATA, restore->smiDacRegs[i][0]);
	    VGAOUT8(pSmi, VGA_DAC_DATA, restore->smiDacRegs[i][1]);
	    VGAOUT8(pSmi, VGA_DAC_DATA, restore->smiDacRegs[i][2]);
	}
	for (i = 0, offset = 2; i < 8192; i++, offset += 8) {
	    *(pSmi->FBBase + offset) = restore->smiFont[i];
	}

	if (SMI_LYNXM_SERIES(pSmi->Chipset)) {
	    /* Restore secondary registers */
	    VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E,
			  restore->CR90[14] | 0x20);

	    VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33_2);
	    for (i = 0; i < 14; i++) {
		VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i,
			      restore->CR40_2[i]);
	    }
	    VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9F, restore->CR9F_2);

	    /* Restore primary registers */
	    VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9E,
			  restore->CR90[14] & ~0x20);

	    VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33);
	    for (i = 0; i < 14; i++) {
		VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i,
			      restore->CR40[i]);
	    }
	    VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x9F, restore->CR9F);

	    /* Restore common registers */
	    VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x30, restore->CR30);
	    VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A, restore->CR3A);

	    for (i = 0; i < 15; i++)
		VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x90 + i,
			      restore->CR90[i]);

	    for (i = 0; i < 14; i++)
		VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0xA0 + i,
			      restore->CRA0[i]);

	}else{
	    VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x30, restore->CR30);
	    VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x33, restore->CR33);
	    VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x3A, restore->CR3A);
	    for (i = 0; i < 14; i++) {
		VGAOUT8_INDEX(pSmi, vgaCRIndex, vgaCRData, 0x40 + i,
			      restore->CR40[i]);
	    }
	}

	if (pSmi->Dualhead) {
	    /* dualhead stuff */
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x40, restore->SR40);
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x41, restore->SR41);
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x42, restore->SR42);
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x43, restore->SR43);
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x44, restore->SR44);
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x45, restore->SR45);
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x48, restore->SR48);
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x49, restore->SR49);
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4A, restore->SR4A);
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4B, restore->SR4B);
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x4C, restore->SR4C);

	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x50, restore->SR50);
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x51, restore->SR51);
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x52, restore->SR52);
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x53, restore->SR53);
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x54, restore->SR54);
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x55, restore->SR55);
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x56, restore->SR56);
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x57, restore->SR57);
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x5A, restore->SR5A);

	    /* PLL2 stuff */
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6E, restore->SR6E);
	    VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x6F, restore->SR6F);
	}
    }

    /* Reset the graphics engine */
    WRITE_DPR(pSmi, 0x10, restore->DPR10);
    WRITE_DPR(pSmi, 0x1C, restore->DPR1C);
    WRITE_DPR(pSmi, 0x20, restore->DPR20);
    WRITE_DPR(pSmi, 0x24, restore->DPR24);
    WRITE_DPR(pSmi, 0x28, restore->DPR28);
    WRITE_DPR(pSmi, 0x2C, restore->DPR2C);
    WRITE_DPR(pSmi, 0x30, restore->DPR30);
    WRITE_DPR(pSmi, 0x3C, restore->DPR3C);
    WRITE_DPR(pSmi, 0x40, restore->DPR40);
    WRITE_DPR(pSmi, 0x44, restore->DPR44);

    /* write video controller regs */
    WRITE_VPR(pSmi, 0x00, restore->VPR00);
    WRITE_VPR(pSmi, 0x0C, restore->VPR0C);
    WRITE_VPR(pSmi, 0x10, restore->VPR10);

    if(pSmi->Chipset == SMI_COUGAR3DR) {
	WRITE_FPR(pSmi, FPR00, restore->FPR00_);
	WRITE_FPR(pSmi, FPR0C, restore->FPR0C_);
	WRITE_FPR(pSmi, FPR10, restore->FPR10_);
    }

    WRITE_CPR(pSmi, 0x00, restore->CPR00);

    if (xf86GetVerbosity() > 1) {
	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, VERBLEV,
		       "Done restoring mode.  Register dump:\n");
	SMI_PrintRegs(pScrn);
    }

    vgaHWProtect(pScrn, FALSE);

    LEAVE();
}