static void
VT1621ModeCrtc(xf86CrtcPtr crtc, DisplayModePtr mode)
{
	ScrnInfoPtr pScrn = crtc->scrn;
	vgaHWPtr hwp = VGAHWPTR(pScrn);
	VIAPtr pVia = VIAPTR(pScrn);
	VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
	struct VT1621TableRec Table = VT1621Table[VT1621ModeIndex(pScrn, mode)];

    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1621ModeCrtc\n"));

    if (pVia->IsSecondary) {
        hwp->writeCrtc(hwp, 0x6A, 0x80);
        hwp->writeCrtc(hwp, 0x6B, 0x20);
        hwp->writeCrtc(hwp, 0x6C, 0x80);

        /* Disable LCD Scaling */
        if (!pVia->SAMM || pVia->FirstInit)
            hwp->writeCrtc(hwp, 0x79, 0x00);

    } else {
        hwp->writeCrtc(hwp, 0x6A, 0x00);
        hwp->writeCrtc(hwp, 0x6B, 0x80);
        hwp->writeCrtc(hwp, 0x6C, Table.PrimaryCR6C);
    }
    pBIOSInfo->ClockExternal = TRUE;
    ViaCrtcMask(hwp, 0x6A, 0x40, 0x40);
    ViaCrtcMask(hwp, 0x6C, 0x01, 0x01);
}
void
CHIPSHWSetMmioFuncs(ScrnInfoPtr pScrn, CARD8 *base, int offset)
{
    vgaHWPtr hwp = VGAHWPTR(pScrn);

    hwp->writeCrtc		= chipsMmioWriteCrtc;
    hwp->readCrtc		= chipsMmioReadCrtc;
    hwp->writeGr		= chipsMmioWriteGr;
    hwp->readGr			= chipsMmioReadGr;
    hwp->writeAttr		= chipsMmioWriteAttr;
    hwp->readAttr		= chipsMmioReadAttr;
    hwp->writeSeq		= chipsMmioWriteSeq;
    hwp->readSeq		= chipsMmioReadSeq;
    hwp->writeMiscOut		= chipsMmioWriteMiscOut;
    hwp->readMiscOut		= chipsMmioReadMiscOut;
    hwp->enablePalette		= chipsMmioEnablePalette;
    hwp->disablePalette		= chipsMmioDisablePalette;
    hwp->writeDacMask		= chipsMmioWriteDacMask;
    hwp->readDacMask		= chipsMmioReadDacMask;
    hwp->writeDacWriteAddr	= chipsMmioWriteDacWriteAddr;
    hwp->writeDacReadAddr	= chipsMmioWriteDacReadAddr;
    hwp->writeDacData		= chipsMmioWriteDacData;
    hwp->readDacData		= chipsMmioReadDacData;
    hwp->readST00               = chipsMmioReadST00;
    hwp->readST01               = chipsMmioReadST01;
    hwp->readFCR               = chipsMmioReadFCR;
    hwp->writeFCR              = chipsMmioWriteFCR;
    hwp->MMIOBase		= base;
    hwp->MMIOOffset		= offset;
}
예제 #3
0
static void
neo_I2CGetBits(I2CBusPtr b, int *clock, int *data) {
    unsigned int reg;
    vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]);
    
    reg = VGArGR(0xA1);
    *clock = 1 /* (reg & 0x?? ) */;
    *data  = (reg & 0x8) != 0;
    /*ErrorF("neo_I2CGetBits: %d %d\n", *clock, *data);*/
}
예제 #4
0
/* This function is used to debug, it prints out the contents of Lynx regs */
void
SMILynx_PrintRegs(ScrnInfoPtr pScrn)
{
    unsigned char i;
    SMIPtr pSmi = SMIPTR(pScrn);
    vgaHWPtr hwp = VGAHWPTR(pScrn);
    int vgaCRIndex = hwp->IOBase + VGA_CRTC_INDEX_OFFSET;
    int vgaCRReg   = hwp->IOBase + VGA_CRTC_DATA_OFFSET;
    int vgaStatus  = hwp->IOBase + VGA_IN_STAT_1_OFFSET;

    xf86ErrorFVerb(VERBLEV, "MISCELLANEOUS OUTPUT\n    %02X\n",
		   VGAIN8(pSmi, VGA_MISC_OUT_R));

    xf86ErrorFVerb(VERBLEV, "\nSEQUENCER\n"
		   "    x0 x1 x2 x3  x4 x5 x6 x7  x8 x9 xA xB  xC xD xE xF");
    for (i = 0x00; i <= 0xAF; i++) {
	if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i);
	if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " ");
	xf86ErrorFVerb(VERBLEV, "%02X ",
		       VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, i));
    }

    xf86ErrorFVerb(VERBLEV, "\n\nCRT CONTROLLER\n"
		   "    x0 x1 x2 x3  x4 x5 x6 x7  x8 x9 xA xB  xC xD xE xF");
    for (i = 0x00; i <= 0xAD; i++) {
	if (i == 0x20) i = 0x30;
	if (i == 0x50) i = 0x90;
	if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i);
	if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " ");
	xf86ErrorFVerb(VERBLEV, "%02X ",
		       VGAIN8_INDEX(pSmi, vgaCRIndex, vgaCRReg, i));
    }

    xf86ErrorFVerb(VERBLEV, "\n\nGRAPHICS CONTROLLER\n"
		   "    x0 x1 x2 x3  x4 x5 x6 x7  x8 x9 xA xB  xC xD xE xF");
    for (i = 0x00; i <= 0x08; i++) {
	if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i);
	if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " ");
	xf86ErrorFVerb(VERBLEV, "%02X ",
		       VGAIN8_INDEX(pSmi, VGA_GRAPH_INDEX, VGA_GRAPH_DATA, i));
    }

    xf86ErrorFVerb(VERBLEV, "\n\nATTRIBUTE 0CONTROLLER\n"
		   "    x0 x1 x2 x3  x4 x5 x6 x7  x8 x9 xA xB  xC xD xE xF");
    for (i = 0x00; i <= 0x14; i++) {
	(void) VGAIN8(pSmi, vgaStatus);
	if ((i & 0xF) == 0x0) xf86ErrorFVerb(VERBLEV, "\n%02X|", i);
	if ((i & 0x3) == 0x0) xf86ErrorFVerb(VERBLEV, " ");
	xf86ErrorFVerb(VERBLEV, "%02X ",
		       VGAIN8_INDEX(pSmi, VGA_ATTR_INDEX, VGA_ATTR_DATA_R, i));
    }
    (void) VGAIN8(pSmi, vgaStatus);
    VGAOUT8(pSmi, VGA_ATTR_INDEX, 0x20);
}
/*
 * Also suited for VT1622A, VT1623, VT1625.
 */
static void
VT1622ModeCrtc(xf86CrtcPtr crtc, DisplayModePtr mode)
{
	ScrnInfoPtr pScrn = crtc->scrn;
	vgaHWPtr hwp = VGAHWPTR(pScrn);
	VIAPtr pVia = VIAPTR(pScrn);
	VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
	struct VT162XTableRec Table;

    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VT1622ModeCrtc\n"));

    if (pBIOSInfo->TVEncoder == VIA_VT1622)
        Table = VT1622Table[VT1622ModeIndex(pScrn, mode)];
    else if (pBIOSInfo->TVEncoder == VIA_VT1625)
        Table = VT1625Table[VT1622ModeIndex(pScrn, mode)];
    else        /* VT1622A/VT1623 */
        Table = VT1623Table[VT1622ModeIndex(pScrn, mode)];

    hwp->writeCrtc(hwp, 0x6A, 0x00);
    hwp->writeCrtc(hwp, 0x6B, 0x00);
    hwp->writeCrtc(hwp, 0x6C, 0x00);

    if (pVia->IsSecondary) {
        hwp->writeCrtc(hwp, 0x6C, Table.SecondaryCR6C);

        ViaCrtcMask(hwp, 0x6A, 0x80, 0x80);
        ViaCrtcMask(hwp, 0x6C, 0x80, 0x80);

        /* CLE266Ax use 2x XCLK. */
        if ((pVia->Chipset == VIA_CLE266) && CLE266_REV_IS_AX(pVia->ChipRev)) {
            ViaCrtcMask(hwp, 0x6B, 0x20, 0x20);

            /* Fix TV clock polarity for CLE266A2. */
            if (pVia->ChipRev == 0x02)
                ViaCrtcMask(hwp, 0x6C, 0x1C, 0x1C);
        }

        /* Disable LCD scaling. */
        if (!pVia->SAMM || pVia->FirstInit)
            hwp->writeCrtc(hwp, 0x79, 0x00);

    } else {
        if ((pVia->Chipset == VIA_CLE266) && CLE266_REV_IS_AX(pVia->ChipRev)) {
            ViaCrtcMask(hwp, 0x6B, 0x80, 0x80);

            /* Fix TV clock polarity for CLE266A2. */
            if (pVia->ChipRev == 0x02)
                hwp->writeCrtc(hwp, 0x6C, Table.PrimaryCR6C);
        }
    }
    pBIOSInfo->ClockExternal = TRUE;
    ViaCrtcMask(hwp, 0x6A, 0x40, 0x40);
    ViaSetTVClockSource(crtc);
}
예제 #6
0
/*
 * This function saves the video state.
 */
static void
LgSave(ScrnInfoPtr pScrn)
{
	CirPtr pCir = CIRPTR(pScrn);
	vgaHWPtr hwp = VGAHWPTR(pScrn);

#ifdef LG_DEBUG
	ErrorF("LgSave\n");
#endif

	vgaHWSave(pScrn, &VGAHWPTR(pScrn)->SavedReg, VGA_SR_ALL);

	pCir->chip.lg->ModeReg.ExtVga[CR1A] = pCir->chip.lg->SavedReg.ExtVga[CR1A] = hwp->readCrtc(hwp, 0x1A);
	pCir->chip.lg->ModeReg.ExtVga[CR1B] = pCir->chip.lg->SavedReg.ExtVga[CR1B] = hwp->readCrtc(hwp, 0x1B);
	pCir->chip.lg->ModeReg.ExtVga[CR1D] = pCir->chip.lg->SavedReg.ExtVga[CR1D] = hwp->readCrtc(hwp, 0x1D);
	pCir->chip.lg->ModeReg.ExtVga[CR1E] = pCir->chip.lg->SavedReg.ExtVga[CR1E] = hwp->readCrtc(hwp, 0x1E);
	pCir->chip.lg->ModeReg.ExtVga[SR07] = pCir->chip.lg->SavedReg.ExtVga[SR07] = hwp->readSeq(hwp, 0x07);
	pCir->chip.lg->ModeReg.ExtVga[SR0E] = pCir->chip.lg->SavedReg.ExtVga[SR0E] = hwp->readSeq(hwp, 0x0E);
	pCir->chip.lg->ModeReg.ExtVga[SR12] = pCir->chip.lg->SavedReg.ExtVga[SR12] = hwp->readSeq(hwp, 0x12);
	pCir->chip.lg->ModeReg.ExtVga[SR13] = pCir->chip.lg->SavedReg.ExtVga[SR13] = hwp->readSeq(hwp, 0x13);
	pCir->chip.lg->ModeReg.ExtVga[SR1E] = pCir->chip.lg->SavedReg.ExtVga[SR1E] = hwp->readSeq(hwp, 0x1E);

	pCir->chip.lg->ModeReg.FORMAT = pCir->chip.lg->SavedReg.FORMAT = memrw(0xC0);
	
	pCir->chip.lg->ModeReg.VSC = pCir->chip.lg->SavedReg.VSC = memrl(0x3FC);
	
	pCir->chip.lg->ModeReg.DTTC = pCir->chip.lg->SavedReg.DTTC = memrw(0xEA);
	
	if (pCir->Chipset == PCI_CHIP_GD5465) {
	    pCir->chip.lg->ModeReg.TileCtrl = pCir->chip.lg->SavedReg.TileCtrl = memrw(0x2C4);
	}
	
	pCir->chip.lg->ModeReg.TILE = pCir->chip.lg->SavedReg.TILE = memrb(0x407);
	
	if (pCir->Chipset == PCI_CHIP_GD5465)
	    pCir->chip.lg->ModeReg.BCLK = pCir->chip.lg->SavedReg.BCLK = memrb(0x2C0);
	else
	    pCir->chip.lg->ModeReg.BCLK = pCir->chip.lg->SavedReg.BCLK = memrb(0x8C);
	
	pCir->chip.lg->ModeReg.CONTROL = pCir->chip.lg->SavedReg.CONTROL = memrw(0x402);
}
예제 #7
0
static void
neo_I2CPutBits(I2CBusPtr b, int clock,  int data) {
    vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]);
    unsigned int reg = 0xF0;

    VGAwCR(0x21,0x00);
    VGAwCR(0x1D,0x01);
    
    if(clock) reg |= 1;
    if(data)  reg |= 0x4;
    VGAwGR(0xA1,reg);
    /*ErrorF("neo_I2CPutBits: %d %d\n", clock, data); */
}
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);
}
예제 #9
0
static unsigned int
chips_ddc1Read(ScrnInfoPtr pScrn)
{
    unsigned char ddc_mask = ((CHIPSPtr)pScrn->driverPrivate)->ddc_mask;
    CHIPSPtr cPtr = CHIPSPTR(pScrn);
    vgaHWPtr hwp = VGAHWPTR(pScrn);
    
    register unsigned int tmp;

    while ((hwp->readST01(hwp)) & 0x08){};
    while (!(hwp->readST01(hwp)) & 0x08){};
    tmp = cPtr->readXR(cPtr, 0x63);
    return (tmp & ddc_mask);
}
예제 #10
0
static void
I810_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags)
{
   I810Ptr pI810 = I810PTR(pScrn);
   vgaHWPtr hwp = VGAHWPTR(pScrn);

   pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y));

   /* wait for retrace */
   while ((hwp->readST01(hwp) & 0x08)) ;
   while (!(hwp->readST01(hwp) & 0x08)) ;

   pI810->DGAViewportStatus = 0;
}
static void
ViaSetTVClockSource(xf86CrtcPtr crtc)
{
	drmmode_crtc_private_ptr iga = crtc->driver_private;
	ScrnInfoPtr pScrn = crtc->scrn;
	VIAPtr pVia = VIAPTR(pScrn);
	VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
	vgaHWPtr hwp = VGAHWPTR(pScrn);

	DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaSetTVClockSource\n"));

    switch(pBIOSInfo->TVEncoder) {
        case VIA_VT1625:
            /* External TV: */
            switch(pVia->Chipset) {
                case VIA_CX700:
                case VIA_VX800:
                case VIA_VX855:
					/* IGA1 */
                    if (!iga->index) {
                        if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP1)
                            ViaCrtcMask(hwp, 0x6C, 0xB0, 0xF0);
                        else if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP0)
                            ViaCrtcMask(hwp, 0x6C, 0x90, 0xF0);
                    } else {
                        /* IGA2 */
                        if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP1)
                            ViaCrtcMask(hwp, 0x6C, 0x0B, 0x0F);
                        else if(pBIOSInfo->TVDIPort == VIA_DI_PORT_DVP0)
                            ViaCrtcMask(hwp, 0x6C, 0x09, 0x0F);
                    }
                    break;
                default:
                    if (!iga->index)
                        ViaCrtcMask(hwp, 0x6C, 0x21, 0x21);
                    else
                        ViaCrtcMask(hwp, 0x6C, 0xA1, 0xA1);
                    break;
            }
            break;
        default:
			if (!iga->index)
				ViaCrtcMask(hwp, 0x6C, 0x50, 0xF0);
			else
				ViaCrtcMask(hwp, 0x6C, 0x05, 0x0F);
            break;
    }

}
static void
AlpI2CPutBits(I2CBusPtr b, int clock,  int data)
{
	unsigned int reg = 0xfc;
	CirPtr pCir = ((CirPtr)b->DriverPrivate.ptr);
	vgaHWPtr hwp = VGAHWPTR(pCir->pScrn);

	if (!AlpI2CSwitchToBus(b))
		return;

	if (clock) reg |= 1;
	if (data)  reg |= 2;
	hwp->writeSeq(hwp, 0x08, reg);
	/* ErrorF("AlpI2CPutBits: %d %d\n", clock, data); */
}
static void
AlpI2CGetBits(I2CBusPtr b, int *clock, int *data)
{
	unsigned int reg;
	CirPtr pCir = ((CirPtr)b->DriverPrivate.ptr);
	vgaHWPtr hwp = VGAHWPTR(pCir->pScrn);

	if (!AlpI2CSwitchToBus(b))
		return;

	reg = hwp->readSeq(hwp, 0x08);
	*clock = (reg & 0x04) != 0;
	*data  = (reg & 0x80) != 0;
	/* ErrorF("AlpI2CGetBits: %d %d\n", *clock, *data); */
}
예제 #14
0
/*
 * SMI_DisplayPowerManagementSet -- Sets VESA Display Power Management
 * Signaling (DPMS) Mode.
 */
void
SMILynx_DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
							  int flags)
{
    SMIPtr	pSmi = SMIPTR(pScrn);
    SMIRegPtr	mode = pSmi->mode;
    vgaHWPtr	hwp = VGAHWPTR(pScrn);

    ENTER();

    /* If we already are in the requested DPMS mode, just return */
    if (pSmi->CurrentDPMS != PowerManagementMode) {
	/* Read the required SR registers for the DPMS handler */
	CARD8 SR01 = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01);

	switch (PowerManagementMode) {
	    case DPMSModeOn:
		SR01 &= ~0x20; /* Screen on */
		mode->SR23 &= ~0xC0; /* Disable chip activity detection */
		break;
	    case DPMSModeStandby:
	    case DPMSModeSuspend:
	    case DPMSModeOff:
		SR01 |= 0x20; /* Screen off */
		mode->SR23 = (mode->SR23 & ~0x07) | 0xD8; /* Enable chip activity detection
							     Enable internal auto-standby mode
							     Enable both IO Write and Host Memory write detect
							     0 minutes timeout */
		break;
	}

	/* Wait for vertical retrace */
	while (hwp->readST01(hwp) & 0x8) ;
	while (!(hwp->readST01(hwp) & 0x8)) ;

	/* Write the registers */
	VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x01, SR01);
	VGAOUT8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x23, mode->SR23);

	/* Set the DPMS mode to every output and CRTC */
	xf86DPMSSet(pScrn, PowerManagementMode, flags);

	/* Save the current power state */
	pSmi->CurrentDPMS = PowerManagementMode;
    }

    LEAVE();
}
예제 #15
0
static unsigned int
SMILynx_ddc1Read(ScrnInfoPtr pScrn)
{
    register vgaHWPtr hwp = VGAHWPTR(pScrn);
    SMIPtr pSmi = SMIPTR(pScrn);
    unsigned int ret;

    ENTER();

    while (hwp->readST01(hwp) & 0x8) ;
    while (!(hwp->readST01(hwp) & 0x8)) ;

    ret = VGAIN8_INDEX(pSmi, VGA_SEQ_INDEX, VGA_SEQ_DATA, 0x72) & 0x08;

    LEAVE(ret);
}
예제 #16
0
static void
I810_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags)
{
   I810Ptr pI810 = I810PTR(pScrn);
   vgaHWPtr hwp = VGAHWPTR(pScrn);

   MARKER();

   pScrn->AdjustFrame(pScrn->pScreen->myNum, x, y, flags);

   /* wait for retrace */
   while ((hwp->readST01(hwp) & 0x08)) ;
   while (!(hwp->readST01(hwp) & 0x08)) ;

   pI810->DGAViewportStatus = 0;
}
예제 #17
0
static Bool
LgModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
{
	vgaHWPtr hwp;
	CirPtr pCir;
	int width;
	Bool VDiv2 = FALSE;
	CARD16 clockData;
	LgLineDataPtr lineData;

#ifdef LG_DEBUG
	ErrorF("LgModeInit %d bpp,   %d   %d %d %d %d   %d %d %d %d\n",
				pScrn->bitsPerPixel,
				mode->Clock,
				mode->HDisplay,
				mode->HSyncStart,
				mode->HSyncEnd,
				mode->HTotal,
				mode->VDisplay,
				mode->VSyncStart,
				mode->VSyncEnd,
				mode->VTotal);

	ErrorF("LgModeInit: depth %d bits\n", pScrn->depth);
#endif

	pCir = CIRPTR(pScrn);
	hwp = VGAHWPTR(pScrn);
	vgaHWUnlock(hwp);

	if (mode->VTotal >= 1024 && !(mode->Flags & V_INTERLACE)) {
		/* For non-interlaced vertical timing >= 1024, the vertical timings */
		/* are divided by 2 and VGA CRTC 0x17 bit 2 is set. */
		if (!mode->CrtcVAdjusted) {
			mode->CrtcVDisplay >>= 1;
			mode->CrtcVSyncStart >>= 1;
			mode->CrtcVSyncEnd >>= 1;
			mode->CrtcVTotal >>= 1;
			mode->CrtcVAdjusted = TRUE;
		}
		VDiv2 = TRUE;
	}
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
    }
}
static void
ViaMMIODisable(ScrnInfoPtr pScrn)
{
    VIAPtr pVia = VIAPTR(pScrn);
    vgaHWPtr hwp = VGAHWPTR(pScrn);

    switch (pVia->Chipset) {
        case VIA_K8M890:
        case VIA_CX700:
        case VIA_P4M900:
        case VIA_VX800:
        case VIA_VX855:
        case VIA_VX900:
            ViaSeqMask(hwp, 0x1A, 0x00, 0x08);
            break;
        default:
            ViaSeqMask(hwp, 0x1A, 0x00, 0x60);
            break;
    }
}
예제 #20
0
/*
 * Fancy little routine stolen from fb
 * We don't do anything but warn really.
 */
void
ViaDoubleCheckCLE266Revision(ScrnInfoPtr pScrn)
{
    vgaHWPtr hwp = VGAHWPTR(pScrn);
    VIAPtr pVia = VIAPTR(pScrn);
    /* Crtc 0x4F is only defined in CLE266Cx */
    CARD8 tmp = hwp->readCrtc(hwp, 0x4F);
    
    hwp->writeCrtc(hwp, 0x4F, 0x55);
    
    if (hwp->readCrtc(hwp, 0x4F) == 0x55) {
	if (CLE266_REV_IS_AX(pVia->ChipRev))
	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "CLE266 Revision seems"
		       " to be Cx, yet %d was detected previously.\n", pVia->ChipRev);
    } else {
	if (CLE266_REV_IS_CX(pVia->ChipRev))
	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "CLE266 Revision seems"
		       " to be Ax, yet %d was detected previously.\n", pVia->ChipRev);
    }
    hwp->writeCrtc(hwp, 0x4F, tmp);
}
/*
 * Switch between internal I2C bus and external (DDC) bus.
 * There is one I2C port controlled bu SR08 and the programmable
 * outputs control a multiplexer.
 */
static Bool
AlpI2CSwitchToBus(I2CBusPtr b)
{
	CirPtr pCir = ((CirPtr)b->DriverPrivate.ptr);
	vgaHWPtr hwp = VGAHWPTR(pCir->pScrn);
	CARD8 reg = hwp->readGr(hwp, 0x17);
	if (b == pCir->I2CPtr1) {
	    if ((reg & 0x60) == 0)
  		return TRUE;
	    reg &= ~0x60;
	}
	else if(b == pCir->I2CPtr2) {
	    if ((reg & 0x60) != 0)
  		return TRUE;
	    reg |= 0x60;
	} else 	return FALSE;

	/* ErrorF("AlpI2CSwitchToBus: \"%s\"\n", b->BusName); */
	hwp->writeGr(hwp, 0x17, reg);
	return TRUE;
}
예제 #22
0
/*
 * TsengCrtcDPMSSet --
 *
 * Sets VESA Display Power Management Signaling (DPMS) Mode.
 * This routine is for the ET4000W32P rev. c and later, which can
 * use CRTC indexed register 34 to turn off H/V Sync signals.
 *
 * '97 Harald Nordgård Hansen
 */
void
TsengCrtcDPMSSet(ScrnInfoPtr pScrn,
    int PowerManagementMode, int flags)
{
    unsigned char seq1, crtc34;
    int iobase = VGAHWPTR(pScrn)->IOBase;

    xf86EnableAccess(pScrn);
    switch (PowerManagementMode) {
    case DPMSModeOn:
    default:
	/* Screen: On; HSync: On, VSync: On */
	seq1 = 0x00;
	crtc34 = 0x00;
	break;
    case DPMSModeStandby:
	/* Screen: Off; HSync: Off, VSync: On */
	seq1 = 0x20;
	crtc34 = 0x01;
	break;
    case DPMSModeSuspend:
	/* Screen: Off; HSync: On, VSync: Off */
	seq1 = 0x20;
	crtc34 = 0x20;
	break;
    case DPMSModeOff:
	/* Screen: Off; HSync: Off, VSync: Off */
	seq1 = 0x20;
	crtc34 = 0x21;
	break;
    }
    outb(0x3C4, 0x01);		       /* Select SEQ1 */
    seq1 |= inb(0x3C5) & ~0x20;
    outb(0x3C5, seq1);
    outb(iobase + 4, 0x34);	       /* Select CRTC34 */
    crtc34 |= inb(iobase + 5) & ~0x21;
    outb(iobase + 5, crtc34);
}
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);
    }
  }
}
static void
ViaMMIOEnable(ScrnInfoPtr pScrn)
{
    VIAPtr pVia = VIAPTR(pScrn);
    vgaHWPtr hwp = VGAHWPTR(pScrn);

    switch (pVia->Chipset) {
        case VIA_K8M890:
        case VIA_CX700:
        case VIA_P4M900:
        case VIA_VX800:
        case VIA_VX855:
        case VIA_VX900:
            ViaSeqMask(hwp, 0x1A, 0x08, 0x08);
            break;
        default:
            if (pVia->IsSecondary)
                ViaSeqMask(hwp, 0x1A, 0x38, 0x38);
            else
                ViaSeqMask(hwp, 0x1A, 0x68, 0x68);
            break;
    }
}
예제 #25
0
/* XXX We need to get rid of this PIO (MArk) */
static int
LgCountRam(ScrnInfoPtr pScrn)
{
	vgaHWPtr hwp = VGAHWPTR(pScrn);
	CARD8 SR14;

	vgaHWProtect(pScrn, TRUE);

	/* The ROM BIOS scratchpad registers contain,
	   among other things, the amount of installed
	   RDRAM on the laguna chip. */
	SR14 = hwp->readSeq(hwp, 0x14);

	ErrorF("Scratch Pads: 0:%02x 1:%02x 2:%02x 3:%02x\n",
		hwp->readSeq(hwp, 9), hwp->readSeq(hwp, 10),
		SR14, hwp->readSeq(hwp, 0x15));

	vgaHWProtect(pScrn, FALSE);

	return 1024 * ((SR14&0x7) + 1);

	/* !!! This function seems to be incorrect... */
}
예제 #26
0
Bool
ViaVbeSaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function)
{
    VIAPtr pVia = VIAPTR(pScrn);
    vgaHWPtr hwp = VGAHWPTR(pScrn);

    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaVbeSaveRestore\n"));

    if ((MODE_QUERY < 0) || (function > MODE_RESTORE))
        return (FALSE);

    if (function == MODE_SAVE)
        pVia->SavedReg.SR1A = hwp->readSeq(hwp, 0x1A);

    /* Query amount of memory to save state. */
    if ((function == MODE_QUERY) ||
        ((function == MODE_SAVE) && (pVia->vbeMode.state == NULL))) {

        /* Make sure we save at least this information in case of failure. */
        (void)VBEGetVBEMode(pVia->pVbe, &(pVia->vbeMode.stateMode));

        if (pVia->vbeMode.major > 1) {
            if (!VBESaveRestore(pVia->pVbe, function,
                                (pointer) & (pVia->vbeMode.state),
                                &(pVia->vbeMode.stateSize),
                                &(pVia->vbeMode.statePage))) {
                xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
                           "VBESaveRestore failed\n");
                return FALSE;
            }
        }
    }

    /* Save/Restore Super VGA state. */
    if (function != MODE_QUERY) {
        Bool retval = TRUE;

        if (pVia->vbeMode.major > 1) {
            if (function == MODE_RESTORE)
                memcpy(pVia->vbeMode.state, pVia->vbeMode.pstate,
                       pVia->vbeMode.stateSize);

            if ((retval = VBESaveRestore(pVia->pVbe, function,
                                         (pointer) & (pVia->vbeMode.state),
                                         &(pVia->vbeMode.stateSize),
                                         &(pVia->vbeMode.statePage)))
                && (function == MODE_SAVE)) {
                /* Do not rely on the memory not being touched. */
                if (pVia->vbeMode.pstate == NULL)
                    pVia->vbeMode.pstate = malloc(pVia->vbeMode.stateSize);
                memcpy(pVia->vbeMode.pstate, pVia->vbeMode.state,
                       pVia->vbeMode.stateSize);
            }
        }

        if (function == MODE_RESTORE) {
            if (!VBESetVBEMode(pVia->pVbe, pVia->vbeMode.stateMode, NULL)) {
                xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
                           "VBESetVBEMode failed\n");
            }
        }

        if (!retval)
            return (FALSE);
    }

    return (TRUE);
}
예제 #27
0
void S3TiDAC_Init(ScrnInfoPtr pScrn, DisplayModePtr mode)
{
        S3Ptr pS3 = S3PTR(pScrn);
        vgaHWPtr hwp = VGAHWPTR(pScrn);
        vgaRegPtr pVga = &hwp->ModeReg;
        int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
	unsigned char tmp, tmp1, tmp2;

	S3TiDACSetClock(pScrn, mode->Clock, 2);
	outb(vgaCRIndex, 0x42);
	tmp = inb(vgaCRReg) & 0xf0;
	outb(vgaCRReg, tmp | 0x02);
	usleep(150000);

	outb(0x3c4, 1);
	tmp2 = inb(0x3c5);
	outb(0x3c5, tmp2 | 0x20);	/* blank */

	tmp = pVga->MiscOutReg;
	pVga->MiscOutReg |= 0xc0;
	tmp1 = 0x00;
	if (!(tmp & 0x80))
		tmp1 |= 0x02;
      	if (!(tmp & 0x40))
		tmp1 |= 0x01;

	S3OutTiIndReg(pScrn, TIDAC_general_ctrl, 0x00, tmp1);
	S3OutTiIndReg(pScrn, 0x0e, 0x00, 0x00);

	/* XXX do 3020 input_clock_sel */

	outb(vgaCRIndex, 0x65);
	/* XXX 3025 */
	outb(vgaCRReg, 0x00);

	/* XXX 3025 */
	outb(vgaCRIndex, 0x40);
	outb(vgaCRReg, 0x11);
	outb(vgaCRIndex, 0x55);
	outb(vgaCRReg, 0x00);

	if (pScrn->bitsPerPixel > 8)
		S3OutTiIndReg(pScrn, TIDAC_auxiliary_ctrl, 0x00, 0x00);
	else
		S3OutTiIndReg(pScrn, TIDAC_auxiliary_ctrl, 0x00, 0x01);

	switch (pScrn->depth) {
	case 8:
		S3OutTiIndReg(pScrn, TIDAC_output_clock_select, 0x00,
			      0x4b);
		outb(vgaCRIndex, 0x66);
		tmp = inb(vgaCRReg);
		if (mode->Clock > 80000)
			outb(vgaCRReg, (tmp & 0xf8) | 0x02);
		else
			outb(vgaCRReg, (tmp & 0xf8) | 0x03);
		break;
	case 16:
		S3OutTiIndReg(pScrn, TIDAC_output_clock_select, 0x00,
			      0x4a);
		outb(vgaCRIndex, 0x66);
		tmp = inb(vgaCRReg);
		if (mode->Clock > 80000)
			outb(vgaCRReg, (tmp & 0xf8) | 0x01);
		else
			outb(vgaCRReg, (tmp & 0xf8) | 0x02);
		break;
	case 24:
		S3OutTiIndReg(pScrn, TIDAC_output_clock_select, 0x00,
			      (0x40 | 0x08 | 0x01));
		outb(vgaCRIndex, 0x66);
		tmp = inb(vgaCRReg);
		if (mode->Clock > 80000)
			outb(vgaCRReg, (tmp & 0xf8) | 0x00);
		else
			outb(vgaCRReg, (tmp & 0xf8) | 0x01);
		break;
	}

	outb(vgaCRIndex, 0x58);
	tmp = inb(vgaCRReg);
	outb(vgaCRReg, (tmp & 0xbf) | 0x40);

	switch(pScrn->depth) {
	case 8:
		S3OutTiIndReg(pScrn, TIDAC_true_color_ctrl, 0x00, 0x80);
		S3OutTiIndReg(pScrn, TIDAC_multiplex_ctrl, 0x00, 0x1c);
		break;
	case 15:
		S3OutTiIndReg(pScrn, TIDAC_true_color_ctrl, 0x00, 0x4c);
		S3OutTiIndReg(pScrn, TIDAC_multiplex_ctrl, 0x00, 0x04);
		S3OutTiIndReg(pScrn, TIDAC_key_ctrl, 0x00, 0x01);
		break;
	case 16:
		S3OutTiIndReg(pScrn, TIDAC_true_color_ctrl, 0x00, 0x4d);
		S3OutTiIndReg(pScrn, TIDAC_multiplex_ctrl, 0x00, 0x04);
		S3OutTiIndReg(pScrn, TIDAC_key_ctrl, 0x00, 0x01);
		break;
	case 24:
		S3OutTiIndReg(pScrn, TIDAC_true_color_ctrl, 0x00, 0x4e);
		S3OutTiIndReg(pScrn, TIDAC_multiplex_ctrl, 0x00, 0x04);
		S3OutTiIndReg(pScrn, TIDAC_key_ctrl, 0x00, 0x01);
		break;
	}

	S3OutTiIndReg(pScrn, TIDAC_general_io_ctrl, 0x00, 0x1f);
	S3OutTiIndReg(pScrn, TIDAC_general_io_data, 0x00, 0x01);
	S3OutTiIndReg(pScrn, TIDAC_general_io_ctrl, 0x00, 0x00);
	S3OutTiIndReg(pScrn, TIDAC_misc_ctrl, 0xf0, (0x04 | 0x08));

	outb(vgaCRIndex, 0x6d);
	if (pS3->s3Bpp == 1)
		if (mode->Clock > 80000)
			outb(vgaCRReg, 0x02);
		else
			outb(vgaCRReg, 0x03);
	else if (pS3->s3Bpp == 2)
		if (mode->Clock > 80000)
			outb(vgaCRReg, 0x00);
		else
			outb(vgaCRReg, 0x01);
	else
		outb(vgaCRReg, 0x00);

	S3OutTiIndReg(pScrn, TIDAC_sense_test, 0x00, 0x00);

	if (pS3->s3Bpp > 1)
	{
		int j;

		outb(0x3c6, 0xff);
		outb(0x3c8, 0x00);
		for(j=0; j<768; j++) {
			outb(0x3c9, j);
			outb(0x3c9, j);
			outb(0x3c9, j);
		}
	}

	outb(0x3c4, 1);
	outb(0x3c5, tmp2);	/* unblank */
}
void
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)
	return;

    if (hwp->Base == NULL) {
	doMap = TRUE;
	if (!vgaHWMapMem(scrninfp)) {
	    xf86DrvMsg(scrninfp->scrnIndex, X_ERROR,
		    "vgaHWRestoreFonts: vgaHWMapMem() failed\n");
	    return;
	}
    }

    /* save the registers that are needed here */
    miscOut = hwp->readMiscOut(hwp);
    attr10 = hwp->readAttr(hwp, 0x10);
    gr1 = hwp->readGr(hwp, 0x01);
    gr3 = hwp->readGr(hwp, 0x03);
    gr4 = hwp->readGr(hwp, 0x04);
    gr5 = hwp->readGr(hwp, 0x05);
    gr6 = hwp->readGr(hwp, 0x06);
    gr8 = hwp->readGr(hwp, 0x08);
    seq2 = hwp->readSeq(hwp, 0x02);
    seq4 = hwp->readSeq(hwp, 0x04);

    /* save hwp->IOBase and temporarily set it for colour mode */
    savedIOBase = hwp->IOBase;
    hwp->IOBase = VGA_IOBASE_COLOR;

    /* Force into colour mode */
    hwp->writeMiscOut(hwp, miscOut | 0x01);

    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
     * copy the font-info and saved text.
     *
     * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
     */
#if 0
    hwp->writeAttr(hwp, 0x10, 0x01);   /* graphics mode */
#endif
    if (scrninfp->depth == 4) {
	/* GJA */
	hwp->writeGr(hwp, 0x03, 0x00);  /* don't rotate, write unmodified */
	hwp->writeGr(hwp, 0x08, 0xFF);  /* write all bits in a byte */
	hwp->writeGr(hwp, 0x01, 0x00);  /* all planes come from CPU */
    }

    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->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->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->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->writeGr(hwp, 0x04, 0x01);  /* read plane 1 */
	slowbcopy_tobus((unsigned char *)hwp->TextInfo + TEXT_AMOUNT,
		hwp->Base, TEXT_AMOUNT);
    }

    /* restore the registers that were changed */
    hwp->writeMiscOut(hwp, miscOut);
    hwp->writeAttr(hwp, 0x10, attr10);
    hwp->writeGr(hwp, 0x01, gr1);
    hwp->writeGr(hwp, 0x03, gr3);
    hwp->writeGr(hwp, 0x04, gr4);
    hwp->writeGr(hwp, 0x05, gr5);
    hwp->writeGr(hwp, 0x06, gr6);
    hwp->writeGr(hwp, 0x08, gr8);
    hwp->writeSeq(hwp, 0x02, seq2);
    hwp->writeSeq(hwp, 0x04, seq4);
    hwp->IOBase = savedIOBase;

    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
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");
	    return;
	}
    }

    /* If in graphics mode, don't save anything */
    attr10 = hwp->readAttr(hwp, 0x10);
    if (attr10 & 0x01)
	return;

    /* save the registers that are needed here */
    miscOut = hwp->readMiscOut(hwp);
    gr4 = hwp->readGr(hwp, 0x04);
    gr5 = hwp->readGr(hwp, 0x05);
    gr6 = hwp->readGr(hwp, 0x06);
    seq2 = hwp->readSeq(hwp, 0x02);
    seq4 = hwp->readSeq(hwp, 0x04);

    /* save hwp->IOBase and temporarily set it for colour mode */
    savedIOBase = hwp->IOBase;
    hwp->IOBase = VGA_IOBASE_COLOR;

    /* Force into colour mode */
    hwp->writeMiscOut(hwp, miscOut | 0x01);

    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
     */
    /*
     * Here we temporarily switch to 16 colour planar mode, to simply
     * copy the font-info
     *
     * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
     */
#if 0
    hwp->writeAttr(hwp, 0x10, 0x01);   /* graphics mode */
#endif
    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 = malloc(FONT_AMOUNT))) {
	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 = malloc(FONT_AMOUNT))) {
	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 = malloc(2 * TEXT_AMOUNT))) {
	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->writeGr(hwp, 0x04, 0x01);  /* read plane 1 */
	slowbcopy_frombus(hwp->Base,
		(unsigned char *)hwp->TextInfo + TEXT_AMOUNT, TEXT_AMOUNT);
    }

    /* Restore clobbered registers */
    hwp->writeAttr(hwp, 0x10, attr10);
    hwp->writeGr(hwp, 0x04, gr4);
    hwp->writeGr(hwp, 0x05, gr5);
    hwp->writeGr(hwp, 0x06, gr6);
    hwp->writeSeq(hwp, 0x02, seq2);
    hwp->writeSeq(hwp, 0x04, seq4);
    hwp->writeMiscOut(hwp, miscOut);
    hwp->IOBase = savedIOBase;

    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);
}
예제 #30
0
/* Mandatory */
Bool
LgPreInit(ScrnInfoPtr pScrn, int flags)
{
	CirPtr pCir;
	vgaHWPtr hwp;
	MessageType from;
	int i;
	ClockRangePtr clockRanges;
	int fbPCIReg, ioPCIReg;
	char *s;

	if (flags & PROBE_DETECT)  {
	  cirProbeDDC( pScrn, xf86GetEntityInfo(pScrn->entityList[0])->index );
	  return TRUE;
	}
	
#ifdef LG_DEBUG
	ErrorF("LgPreInit\n");
#endif

	/* Check the number of entities, and fail if it isn't one. */
	if (pScrn->numEntities != 1)
		return FALSE;

	/* The vgahw module should be loaded here when needed */
	if (!xf86LoadSubModule(pScrn, "vgahw"))
		return FALSE;

	xf86LoaderReqSymLists(vgahwSymbols, NULL);

	/*
	 * Allocate a vgaHWRec
	 */
	if (!vgaHWGetHWRec(pScrn))
		return FALSE;

	hwp = VGAHWPTR(pScrn);
	vgaHWGetIOBase(hwp);

	/* Allocate the LgRec driverPrivate */
	if (!LgGetRec(pScrn))
		return FALSE;

	pCir = CIRPTR(pScrn);
	pCir->pScrn = pScrn;
	pCir->PIOReg = hwp->PIOOffset + 0x3CE;

	/* Get the entity, and make sure it is PCI. */
	pCir->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
	if (pCir->pEnt->location.type != BUS_PCI)
		return FALSE;
	pCir->Chipset = pCir->pEnt->chipset;

	/* Find the PCI info for this screen */
	pCir->PciInfo = xf86GetPciInfoForEntity(pCir->pEnt->index);
	pCir->PciTag = pciTag(pCir->PciInfo->bus,
								pCir->PciInfo->device,
								pCir->PciInfo->func);

	if (xf86LoadSubModule(pScrn, "int10")) {
	    xf86Int10InfoPtr int10InfoPtr;
	    xf86LoaderReqSymLists(int10Symbols, NULL);
	    
	    int10InfoPtr = xf86InitInt10(pCir->pEnt->index);

	    if (int10InfoPtr)
		xf86FreeInt10(int10InfoPtr);
	}

	/* Set pScrn->monitor */
	pScrn->monitor = pScrn->confScreen->monitor;

	/*
	 * The first thing we should figure out is the depth, bpp, etc.
	 * We support both 24bpp and 32bpp layouts, so indicate that.
	 */
	if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb |
							SupportConvert32to24 | PreferConvert32to24)) {
		return FALSE;
    }
	/* Check that the returned depth is one we support */
	switch (pScrn->depth) {
	case 8:
	case 15:
	case 16:
	case 24:
	case 32:
		/* OK */
		break;
	default:
		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
			"Given depth (%d) is not supported by this driver\n", pScrn->depth);
		return FALSE;
	}
	xf86PrintDepthBpp(pScrn);

	/* Get the depth24 pixmap format */
	if (pScrn->depth == 24 && pix24bpp == 0)
		pix24bpp = xf86GetBppFromDepth(pScrn, 24);

	/*
	 * This must happen after pScrn->display has been set because
	 * xf86SetWeight references it.
	 */
	if (pScrn->depth > 8) {
		/* The defaults are OK for us */
		rgb zeros = {0, 0, 0};

		/* !!! I think we can force 5-6-5 weight for 16bpp here for
		   the 5462. */

		if (!xf86SetWeight(pScrn, zeros, zeros)) {
			return FALSE;
		} else {
			/* XXX check that weight returned is supported */
			;
		}
	}

	if (!xf86SetDefaultVisual(pScrn, -1))
		return FALSE;


	/* Collect all of the relevant option flags (fill in pScrn->options) */
	xf86CollectOptions(pScrn, NULL);

	/* Process the options */
	if (!(pCir->Options = xalloc(sizeof(LgOptions))))
		return FALSE;
	memcpy(pCir->Options, LgOptions, sizeof(LgOptions));
	xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pCir->Options);

	pScrn->rgbBits = 6; 
	from = X_DEFAULT;
	pCir->HWCursor = FALSE;
	if (xf86GetOptValBool(pCir->Options, OPTION_HW_CURSOR, &pCir->HWCursor))
		from = X_CONFIG;

	xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
		pCir->HWCursor ? "HW" : "SW");
	if (xf86ReturnOptValBool(pCir->Options, OPTION_NOACCEL, FALSE)) {
		pCir->NoAccel = TRUE;
		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
	}
	if (pScrn->bitsPerPixel < 8) {
		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
			"Cannot use in less than 8 bpp\n");
		return FALSE;
	}
	/*
	 * Set the ChipRev, allowing config file entries to
	 * override.
	 */
	if (pCir->pEnt->device->chipRev >= 0) {
		pCir->ChipRev = pCir->pEnt->device->chipRev;
		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
			pCir->ChipRev);
	} else {
		pCir->ChipRev = pCir->PciInfo->chipRev;
	}

	/* Cirrus swapped the FB and IO registers in the 5465 (by design). */
	if (PCI_CHIP_GD5465 == pCir->Chipset) {
		fbPCIReg = 0;
		ioPCIReg = 1;
	} else {
		fbPCIReg = 1;
		ioPCIReg = 0;
	}

	/* Find the frame buffer base address */
	if (pCir->pEnt->device->MemBase != 0) {
		/* Require that the config file value matches one of the PCI values. */
		if (!xf86CheckPciMemBase(pCir->PciInfo, pCir->pEnt->device->MemBase)) {
			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
				"MemBase 0x%08lX doesn't match any PCI base register.\n",
				pCir->pEnt->device->MemBase);
			return FALSE;
		}
		pCir->FbAddress = pCir->pEnt->device->MemBase;
		from = X_CONFIG;
	} else {
		if (pCir->PciInfo->memBase[fbPCIReg] != 0) {
			pCir->FbAddress = pCir->PciInfo->memBase[fbPCIReg] & 0xff000000;
			from = X_PROBED;
		} else {
			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
				"No valid FB address in PCI config space\n");
			LgFreeRec(pScrn);
			return FALSE;
		}
	}
	xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
		(unsigned long)pCir->FbAddress);

	/* Find the MMIO base address */
	if (pCir->pEnt->device->IOBase != 0) {
		/* Require that the config file value matches one of the PCI values. */
		if (!xf86CheckPciMemBase(pCir->PciInfo, pCir->pEnt->device->IOBase)) {
			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
				"IOBase 0x%08lX doesn't match any PCI base register.\n",
				pCir->pEnt->device->IOBase);
			return FALSE;
		}
		pCir->IOAddress = pCir->pEnt->device->IOBase;
		from = X_CONFIG;
	} else {
		if (pCir->PciInfo->memBase[ioPCIReg] != 0) {
			pCir->IOAddress = pCir->PciInfo->memBase[ioPCIReg] & 0xfffff000;
			from = X_PROBED;
		} else {
			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
			"No valid MMIO address in PCI config space\n");
		}
	}
	xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
		(unsigned long)pCir->IOAddress);

	/*
	 * If the user has specified the amount of memory in the XF86Config
	 * file, we respect that setting.
	 */
	if (pCir->pEnt->device->videoRam != 0) {
		pScrn->videoRam = pCir->pEnt->device->videoRam;
		from = X_CONFIG;
	} else {
		pScrn->videoRam = LgCountRam(pScrn);
		from = X_PROBED;
	}
	if (2048 == pScrn->videoRam) {
		/* Two-way interleaving */
		pCir->chip.lg->memInterleave = 0x40;
	} else if (4096 == pScrn->videoRam || 8192 == pScrn->videoRam) {
		/* Four-way interleaving */
		pCir->chip.lg->memInterleave = 0x80;
	} else {
		/* One-way interleaving */
		pCir->chip.lg->memInterleave = 0x00;
	}

	xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
				pScrn->videoRam);

	pCir->FbMapSize = pScrn->videoRam * 1024;
	pCir->IoMapSize = 0x4000;	/* 16K for moment,  will increase */

	pScrn->racIoFlags =   RAC_COLORMAP 
#ifndef EXPERIMENTAL
	  | RAC_VIEWPORT
#endif
;
 	xf86SetOperatingState(resVgaMem, pCir->pEnt->index, ResUnusedOpr);
	
	/* Register the PCI-assigned resources. */
	if (xf86RegisterResources(pCir->pEnt->index, NULL, ResExclusive)) {
		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
			"xf86RegisterResources() found resource conflicts\n");
		return FALSE;
	}

	if (!xf86LoadSubModule(pScrn, "ddc")) {
		LgFreeRec(pScrn);
		return FALSE;
	}
	xf86LoaderReqSymLists(ddcSymbols, NULL);

#if LGuseI2C
	if (!xf86LoadSubModule(pScrn, "i2c")) {
		LgFreeRec(pScrn);
		return FALSE;
	}
	xf86LoaderReqSymLists(i2cSymbols, NULL);
#endif

	/* Read and print the monitor DDC information */
	pScrn->monitor->DDC = LgDoDDC(pScrn);

	/* The gamma fields must be initialised when using the new cmap code */
	if (pScrn->depth > 1) {
		Gamma zeros = {0.0, 0.0, 0.0};

		if (!xf86SetGamma(pScrn, zeros))
			return FALSE;
	}
	if (xf86GetOptValBool(pCir->Options,
			      OPTION_SHADOW_FB,&pCir->shadowFB))
	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowFB %s.\n",
		       pCir->shadowFB ? "enabled" : "disabled");
	    
	if ((s = xf86GetOptValString(pCir->Options, OPTION_ROTATE))) {
	    if(!xf86NameCmp(s, "CW")) {
		/* accel is disabled below for shadowFB */
		pCir->shadowFB = TRUE;
		pCir->rotate = 1;
		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
			   "Rotating screen clockwise - acceleration disabled\n");
	    } else if(!xf86NameCmp(s, "CCW")) {
		pCir->shadowFB = TRUE;
		pCir->rotate = -1;
		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,  "Rotating screen"
			   "counter clockwise - acceleration disabled\n");
	    } else {
		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid"
			   "value for Option \"Rotate\"\n", s);
		xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
			   "Valid options are \"CW\" or \"CCW\"\n");
	    }
	}

	if (pCir->shadowFB && !pCir->NoAccel) {
	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
		       "HW acceleration not supported with \"shadowFB\".\n");
	    pCir->NoAccel = TRUE;
	}
	
	if (pCir->rotate && pCir->HWCursor) {
	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
		       "HW cursor not supported with \"rotate\".\n");
	    pCir->HWCursor = FALSE;
	}
	
	/* We use a programmable clock */
	pScrn->progClock = TRUE;

	/* XXX Set HW cursor use */

	/* Set the min pixel clock */
	pCir->MinClock = 12000;	/* XXX Guess, need to check this */
	xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
				pCir->MinClock / 1000);
	/*
	 * If the user has specified ramdac speed in the XF86Config
	 * file, we respect that setting.
	 */
	if (pCir->pEnt->device->dacSpeeds[0]) {
		ErrorF("Do not specify a Clocks line for Cirrus chips\n");
		return FALSE;
	} else {
		int speed;
		int *p;
		switch (pCir->Chipset) {
		case PCI_CHIP_GD5462:
			p = gd5462_MaxClocks;
			break;
		case PCI_CHIP_GD5464:
		case PCI_CHIP_GD5464BD:
			p = gd5464_MaxClocks;
			break;
		case PCI_CHIP_GD5465:
			p = gd5465_MaxClocks;
			break;
		default:
			ErrorF("???\n");
			return FALSE;
		}
		switch (pScrn->bitsPerPixel) {
		case 8:
			speed = p[1];
			break;
		case 15:
		case 16:
			speed = p[2];
			break;
		case 24:
			speed = p[3];
			break;
		case 32:
			speed = p[4];
			break;
		default:
			/* Should not get here */
			speed = 0;
			break;
		}
		pCir->MaxClock = speed;
		from = X_PROBED;
	}
	xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
				pCir->MaxClock / 1000);

	/*
	 * Setup the ClockRanges, which describe what clock ranges are available,
	 * and what sort of modes they can be used for.
	 */
	clockRanges = xnfcalloc(sizeof(ClockRange), 1);
	clockRanges->next = NULL;
	clockRanges->minClock = pCir->MinClock;
	clockRanges->maxClock = pCir->MaxClock;
	clockRanges->clockIndex = -1;		/* programmable */
	clockRanges->interlaceAllowed = FALSE;	/* XXX check this */
	clockRanges->doubleScanAllowed = FALSE;	/* XXX check this */
	clockRanges->doubleScanAllowed = FALSE;	/* XXX check this */
	clockRanges->doubleScanAllowed = FALSE;	/* XXX check this */
	clockRanges->ClockMulFactor = 1;
	clockRanges->ClockDivFactor = 1;
	clockRanges->PrivFlags = 0;

	/* Depending upon what sized tiles used, either 128 or 256. */
	/* Aw, heck.  Just say 128. */
	pCir->Rounding = 128 >> pCir->BppShift;

	/*
	 * xf86ValidateModes will check that the mode HTotal and VTotal values
	 * don't exceed the chipset's limit if pScrn->maxHValue and
	 * pScrn->maxVValue are set.  Since our CIRValidMode() already takes
	 * care of this, we don't worry about setting them here.
	 */

	i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes,
							clockRanges,
							LgLinePitches[pScrn->bitsPerPixel / 8 - 1],
							0, 0, 128 * 8,
							0, 0, /* Any virtual height is allowed. */
							pScrn->display->virtualX,
							pScrn->display->virtualY,
							pCir->FbMapSize,
							LOOKUP_BEST_REFRESH);

	pCir->chip.lg->lineDataIndex = LgFindLineData(pScrn->displayWidth,
										pScrn->bitsPerPixel);

	if (i == -1) {
		LgFreeRec(pScrn);
		return FALSE;
	}

	/* Prune the modes marked as invalid */
	xf86PruneDriverModes(pScrn);

	if (i == 0 || pScrn->modes == NULL) {
		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
		LgFreeRec(pScrn);
		return FALSE;
	}

	/*
	 * Set the CRTC parameters for all of the modes based on the type
	 * of mode, and the chipset's interlace requirements.
	 *
	 * Calling this is required if the mode->Crtc* values are used by the
	 * driver and if the driver doesn't provide code to set them.  They
	 * are not pre-initialised at all.
	 */
	xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);

	/* Set the current mode to the first in the list */
	pScrn->currentMode = pScrn->modes;

	/* Print the list of modes being used */
	xf86PrintModes(pScrn);

	/* Set display resolution */
	xf86SetDpi(pScrn, 0, 0);

	/* Load bpp-specific modules */
	switch (pScrn->bitsPerPixel) {
	case 8:
	case 16:
	case 24:
	case 32: 
	    if (xf86LoadSubModule(pScrn, "fb") == NULL) {
	         LgFreeRec(pScrn);
		 return FALSE;
	    }
	    xf86LoaderReqSymLists(fbSymbols, NULL);
	    break;
	}

	/* Load XAA if needed */
	if (!pCir->NoAccel) {
		if (!xf86LoadSubModule(pScrn, "xaa")) {
			LgFreeRec(pScrn);
			return FALSE;
		}
		xf86LoaderReqSymLists(xaaSymbols, NULL);
	}

	/* Load ramdac if needed */
	if (pCir->HWCursor) {
		if (!xf86LoadSubModule(pScrn, "ramdac")) {
			LgFreeRec(pScrn);
			return FALSE;
		}
		xf86LoaderReqSymLists(ramdacSymbols, NULL);
	}

	if (pCir->shadowFB) {
	    if (!xf86LoadSubModule(pScrn, "shadowfb")) {
		LgFreeRec(pScrn);
		return FALSE;
	    }
	    xf86LoaderReqSymLists(shadowSymbols, NULL);
	}
	
	return TRUE;
}