/* Open /proc/mtrr. FALSE on failure. Will always fail on Linux 2.0, 
   and will fail on Linux 2.2 with MTRR support configured out,
   so verbosity should be chosen appropriately. */
static Bool
mtrr_open(int verbosity)
{
	/* Only report absence of /proc/mtrr once. */
	static Bool warned = FALSE;

	if (mtrr_fd == MTRR_FD_UNOPENED) { 
		mtrr_fd = open("/proc/mtrr", O_WRONLY);

		if (mtrr_fd < 0)
			mtrr_fd = MTRR_FD_PROBLEM;
	}

	if (mtrr_fd == MTRR_FD_PROBLEM) {
		/* To make sure we only ever warn once, need to check
		   verbosity outside xf86MsgVerb */
		if (!warned && verbosity <= xf86GetVerbosity()) {
			xf86MsgVerb(X_WARNING, verbosity,
				  "System lacks support for changing MTRRs\n");
			warned = TRUE;
		}

		return FALSE;
	}
	else
		return TRUE;
}
示例#2
0
void
SMI_GEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file)
{
	SMIPtr pSmi = SMIPTR(pScrn);
	CARD8 tmp;

	ENTER_PROC("SMI_GEReset");

	if (from_timeout)
	{
		if (pSmi->GEResetCnt++ < 10 || xf86GetVerbosity() > 1)
		{
			xf86DrvMsg(pScrn->scrnIndex,X_INFO,"\tSMI_GEReset called from %s line %d\n", file, line);
		}
	}
	else
	{
		WaitIdleEmpty();
	}

	tmp = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x15);
	VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x15, tmp | 0x30);

	WaitIdleEmpty();

	VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x15, tmp);
	SMI_EngineReset(pScrn);

	LEAVE_PROC("SMI_GEReset");
}
示例#3
0
/* Open /proc/mtrr. FALSE on failure. Will always fail on Linux 2.0, 
   and will fail on Linux 2.2 with MTRR support configured out,
   so verbosity should be chosen appropriately. */
static Bool
mtrr_open(int verbosity)
{
	/* Only report absence of /proc/mtrr once. */
	static Bool warned = FALSE;

	char **fn;
	static char *mtrr_files[] = {
		"/dev/cpu/mtrr",	/* Possible future name */
		"/proc/mtrr",		/* Current name */
		NULL
	};

	if (mtrr_fd == MTRR_FD_UNOPENED) { 
		/* So open it. */
		for (fn = mtrr_files; mtrr_fd < 0 && *fn; fn++)
			mtrr_fd = open(*fn, O_WRONLY);

		if (mtrr_fd < 0)
			mtrr_fd = MTRR_FD_PROBLEM;
	}

	if (mtrr_fd == MTRR_FD_PROBLEM) {
		/* To make sure we only ever warn once, need to check
		   verbosity outside xf86MsgVerb */
		if (!warned && verbosity <= xf86GetVerbosity()) {
			xf86MsgVerb(X_WARNING, verbosity,
				  "System lacks support for changing MTRRs\n");
			warned = TRUE;
		}

		return FALSE;
	}
	else
		return TRUE;
}
示例#4
0
文件: xf86fbman.c 项目: 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;
}
示例#5
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();
}
示例#6
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();
}