static xf86MonPtr
LgDoDDC(ScrnInfoPtr pScrn)
{
	CirPtr pCir = CIRPTR(pScrn);
	xf86MonPtr MonInfo = NULL;

	/* Map the CIR memory and MMIO areas */
	if (!CirMapMem(pCir, pScrn->scrnIndex))
		return FALSE;

#if LGuseI2C
	if (!LgI2CInit(pScrn)) {
		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I2C initialization failed\n");

		goto unmap_out;
	}

	/* Read and output monitor info using DDC2 over I2C bus */
	MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, pCir->I2CPtr1);
	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "I2C Monitor info: %p\n",
		   (void *)MonInfo);
	xf86PrintEDID(MonInfo);
	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of I2C Monitor info\n\n");
#endif /* LGuseI2C */

	xf86SetDDCproperties(pScrn, MonInfo);

unmap_out:
	CirUnmapMem(pCir, pScrn->scrnIndex);

	return MonInfo;
}
Exemple #2
0
static void
LgSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
								int x2, int y2, int w, int h)
{
	const CirPtr pCir = CIRPTR(pScrn);
	const LgPtr pLg = LGPTR(pCir);

	/*
	 * We have set the flag indicating that xdir must be one,
	 * so we can assume that here.
	 */
	if (pLg->blitYDir == -1) {
		y1 += h - 1;
		y2 += h - 1;
	}

	if (pLg->blitTransparent) {
		/* We're doing a transparent blit.  We'll need to point
		   OP2 to the color compare mask. */
		LgWaitQAvail(pCir, 4);
		LgSETTRANSMASK(x1, y1);
	} else {
		LgWaitQAvail(pCir, 3);
	}
	LgSETSRCXY(x1, y1);
	LgSETDSTXY(x2, y2);
	LgSETEXTENTS(w, h);
}
static void
AlpSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
{
    ScreenPtr pScreen = pPixmap->drawable.pScreen;
    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
    CirPtr pCir = CIRPTR(pScrn);
    int dest;
    int hh, ww;
    int pitch = pCir->pitch;
    
    ww = ((x2 - x1) * pScrn->bitsPerPixel / 8) - 1;
    hh = (y2 - y1) - 1;
    dest = y1 * pitch + x1 * pScrn->bitsPerPixel / 8;
    
    WAIT;
    
    /* Width */
    outw(pCir->PIOReg, ((ww << 8) & 0xff00) | 0x20);
    outw(pCir->PIOReg, ((ww) & 0x1f00) | 0x21);
    /* Height */
    outw(pCir->PIOReg, ((hh << 8) & 0xff00) | 0x22);
    outw(pCir->PIOReg, ((hh) & 0x0700) | 0x23);
    
    /* dest */
    outw(pCir->PIOReg, ((dest << 8) & 0xff00) | 0x28);
    outw(pCir->PIOReg, ((dest) & 0xff00) | 0x29);
    outw(pCir->PIOReg, ((dest >> 8) & 0x3f00) | 0x2A);
    if (!pCir->chip.alp->autoStart)
	outw(pCir->PIOReg, 0x0231);
    
#ifdef ALP_DEBUG
    ErrorF("AlpSubsequentSolidFillRect x=%d y=%d w=%d h=%d\n",
	   x1, y1, x2 - x1, y2 - y1);
#endif
}
static void
AlpDone(PixmapPtr pPixmap)
{
    ScreenPtr pScreen = pPixmap->drawable.pScreen;
    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
    CirPtr pCir = CIRPTR(pScrn);
#ifdef ALP_DEBUG
    ErrorF("AlpDone\n");
#endif
}
Exemple #5
0
static void
LgSync(ScrnInfoPtr pScrn)
{
	const CirPtr pCir = CIRPTR(pScrn);
#if 0
	LgPtr pLg = LGPTR(pScrn);
#endif

	while (!LgREADY())
		;
}
Exemple #6
0
static void
LgSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
{
	const CirPtr pCir = CIRPTR(pScrn);

	/* Wait for room in the command queue. */
	LgWaitQAvail(pCir, 2);

	LgSETDSTXY(x, y);
	LgSETEXTENTS(w, h);
}
static Bool
AlpPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
{
    ScreenPtr pScreen = pPixmap->drawable.pScreen;
    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
    CirPtr pCir = CIRPTR(pScrn);
    AlpPtr pAlp = ALPPTR(pCir);
    int pitch = pCir->pitch;
    
#ifdef ALP_DEBUG
    ErrorF("AlpSetupForSolidFill color=%x alu=%x planemask=%x\n",
	   fg, alu, planemask);
#endif
    WAIT;
    
    SetupForRop(alu);
    
    switch (pCir -> Chipset) {
      case PCI_CHIP_GD7548:
	/* The GD7548 does not (apparently) support solid filling
	   directly, it always need an actual source.
	   We therefore use it as a pattern fill with a solid
	   pattern */
      {
	  int source = pAlp->monoPattern8x8;
	  /* source = 8x8 solid mono pattern */
	  outw(pCir->PIOReg, ((source << 8) & 0xff00) | 0x2C);
	  outw(pCir->PIOReg, ((source) & 0xff00) | 0x2D);
	  outw(pCir->PIOReg, ((source >> 8) & 0x3f00) | 0x2E);
	  /* memset() may not be the fastest */
	  memset((char *)pCir->FbBase + pAlp->monoPattern8x8, 0xFF, 8);
	  write_mem_barrier();
	  break;
      }
      default:
	/* GR33 = 0x04 => does not exist on GD7548 */
	outw(pCir->PIOReg, 0x0433);
    }
    
    /* GR30 = color expansion, pattern copy */
    /* Choses 8bpp / 16bpp color expansion */
    outw(pCir->PIOReg, 0xC030 |((pScrn->bitsPerPixel - 8) << 9));
    
    outw(pCir->PIOReg, ((fg << 8) & 0xff00) | 0x01);
    outw(pCir->PIOReg, ((fg) & 0xff00) | 0x11);
    outw(pCir->PIOReg, ((fg >> 8) & 0xff00) | 0x13);
    outw(pCir->PIOReg, 0x15);
    
    /* Set dest pitch */
    outw(pCir->PIOReg, ((pitch << 8) & 0xff00) | 0x24);
    outw(pCir->PIOReg, ((pitch) & 0x1f00) | 0x25);
    
    return TRUE;
}
static void
AlpSync(ScreenPtr pScreen, int marker)
{
    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
    CirPtr pCir = CIRPTR(pScrn);

#ifdef ALP_DEBUG
    ErrorF("AlpSync\n");
#endif
    WAIT_1;
    return;
}
static void
AlpCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, 
	int width, int height)
{
    ScreenPtr pScreen = pDstPixmap->drawable.pScreen;
    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
    CirPtr pCir = CIRPTR(pScrn);
    int source, dest;
    int  hh, ww;
    int decrement = 0;
    int pitch = pCir->pitch;
    
    ww = (width * pScrn->bitsPerPixel / 8) - 1;
    hh = height - 1;
    dest = dstY * pitch + dstX * pScrn->bitsPerPixel / 8;
    source = srcY * pitch + srcX * pScrn->bitsPerPixel / 8;
    if (dest > source) {
	decrement = 1 << 8;
	dest += hh * pitch + ww;
	source += hh * pitch + ww;
    }
    
    WAIT;
    
    outw(pCir->PIOReg, decrement | 0x30);
    
    /* Width */
    outw(pCir->PIOReg, ((ww << 8) & 0xff00) | 0x20);
    outw(pCir->PIOReg, ((ww) & 0x1f00) | 0x21);
    /* Height */
    outw(pCir->PIOReg, ((hh << 8) & 0xff00) | 0x22);
    outw(pCir->PIOReg, ((hh) & 0x0700) | 0x23);
    
    
    /* source */
    outw(pCir->PIOReg, ((source << 8) & 0xff00) | 0x2C);
    outw(pCir->PIOReg, ((source) & 0xff00) | 0x2D);
    outw(pCir->PIOReg, ((source >> 8) & 0x3f00)| 0x2E);
    
    /* dest */
    outw(pCir->PIOReg, ((dest  << 8) & 0xff00) | 0x28);
    outw(pCir->PIOReg, ((dest) & 0xff00) | 0x29);
    outw(pCir->PIOReg, ((dest >> 8) & 0x3f00) | 0x2A);
    if (!pCir->chip.alp->autoStart)
	outw(pCir->PIOReg, 0x0231);
    
#ifdef ALP_DEBUG
    ErrorF("AlpCopy x1=%d y1=%d x2=%d y2=%d w=%d h=%d\n",
	   srcX, srcY, dstX, dstY, width, height);
    ErrorF("AlpSCopy s=%d d=%d ww=%d hh=%d\n",
	   source, dest, ww, hh);
#endif
}
Bool
AlpI2CInit(ScrnInfoPtr pScrn)
{
	CirPtr pCir = CIRPTR(pScrn);
	I2CBusPtr I2CPtr;

#ifdef ALP_DEBUG
	ErrorF("AlpI2CInit\n");
#endif

	switch(pCir->Chipset) {
	case PCI_CHIP_GD5446:
	case PCI_CHIP_GD5480:
		break;
	default:
		return FALSE;
	}


	I2CPtr = xf86CreateI2CBusRec();
	if (!I2CPtr) return FALSE;

	pCir->I2CPtr1 = I2CPtr;

	I2CPtr->BusName    = "I2C bus 1";
	I2CPtr->scrnIndex  = pScrn->scrnIndex;
	I2CPtr->I2CPutBits = AlpI2CPutBits;
	I2CPtr->I2CGetBits = AlpI2CGetBits;
	I2CPtr->DriverPrivate.ptr = pCir;

	if (!xf86I2CBusInit(I2CPtr))
		return FALSE;

	I2CPtr = xf86CreateI2CBusRec();
	if (!I2CPtr) return FALSE;

	pCir->I2CPtr2 = I2CPtr;

	I2CPtr->BusName    = "I2C bus 2";
	I2CPtr->scrnIndex  = pScrn->scrnIndex;
	I2CPtr->I2CPutBits = AlpI2CPutBits;
	I2CPtr->I2CGetBits = AlpI2CGetBits;
	I2CPtr->DriverPrivate.ptr = pCir;

	if (!xf86I2CBusInit(I2CPtr))
		return FALSE;

	return TRUE;
}
Exemple #11
0
static void
LgSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
			unsigned int planemask)
{

	const CirPtr pCir = CIRPTR(pScrn);

	color = LgExpandColor(color, pScrn->bitsPerPixel);

	LgWaitQAvail(pCir, 4);

	LgSETBACKGROUND(color);
	LgSETROP(lgRop[rop]);
	LgSETMODE(SCR2SCR | COLORFILL);
	LgSetBitmask(pCir, planemask);
}
static void
AlpAccelEngineInit(ScreenPtr pScreen)
{
    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
    CirPtr pCir = CIRPTR(pScrn);

    outw(pCir->PIOReg, 0x200E); /* enable writes to gr33 */
    /* Setup things for autostart */
    if (pCir->properties & ACCEL_AUTOSTART) {
        outw(pCir->PIOReg, 0x8031); /* enable autostart */
	pCir->chip.alp->waitMsk = 0x10;
	pCir->chip.alp->autoStart = TRUE;
    } else {
        pCir->chip.alp->waitMsk = 0x1;
	pCir->chip.alp->autoStart = FALSE;
    }
}
static Bool
LgGetRec(ScrnInfoPtr pScrn)
{
	CirPtr pCir;

	if (pScrn->driverPrivate != NULL)
		return TRUE;

	pScrn->driverPrivate = xnfcalloc(sizeof(CirRec), 1);
	((CirPtr)pScrn->driverPrivate)->chip.lg = xnfcalloc(sizeof(LgRec),1);

	/* Initialize it */
	pCir = CIRPTR(pScrn);
	pCir->chip.lg->oldBitmask = 0x00000000;

	return TRUE;
}
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;
	}
/*
 * 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);
}
Bool
AlpEXAInit(ScreenPtr pScreen)
{
    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
    CirPtr pCir = CIRPTR(pScrn);

    AlpAccelEngineInit(pScreen);

    pCir->ExaDriver->exa_major = EXA_VERSION_MAJOR;
    pCir->ExaDriver->exa_minor = EXA_VERSION_MINOR;

    pCir->ExaDriver->memoryBase = (char *)pCir->FbBase + pScrn->fbOffset;
    pCir->ExaDriver->flags = EXA_OFFSCREEN_PIXMAPS | EXA_OFFSCREEN_ALIGN_POT;

#if EXA_VERSION_MAJOR > 2 || (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 3)
    pCir->ExaDriver->maxPitchBytes = 16320;
#endif
    /* Pitch alignment is in sets of 8 pixels, and we need to cover 32bpp, so it's 32 bytes */
    pCir->ExaDriver->pixmapPitchAlign = 32;
    pCir->ExaDriver->pixmapOffsetAlign = 32;
    pCir->ExaDriver->maxX = 2048;
    pCir->ExaDriver->maxY = 2048;
    
    pCir->ExaDriver->PrepareSolid = AlpPrepareSolid;
    pCir->ExaDriver->Solid = AlpSolid;
    pCir->ExaDriver->DoneSolid =AlpDone;
    
    pCir->ExaDriver->PrepareCopy = AlpPrepareCopy;
    pCir->ExaDriver->Copy = AlpCopy;
    pCir->ExaDriver->DoneCopy = AlpDone;

    pCir->ExaDriver->WaitMarker = AlpSync;

    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
	       "Initializing EXA driver...\n");
    if (!exaDriverInit(pScreen, pCir->ExaDriver)) {
	free(pCir->ExaDriver);
	return FALSE;
    }
    return TRUE;
}
Bool
LgI2CInit(ScrnInfoPtr pScrn)
{
	CirPtr pCir = CIRPTR(pScrn);
	I2CBusPtr I2CPtr;

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

	I2CPtr = xf86CreateI2CBusRec();
	if (!I2CPtr) return FALSE;

	pCir->I2CPtr1 = I2CPtr;

	I2CPtr->BusName				= "I2C bus 1";
	I2CPtr->scrnIndex			= pScrn->scrnIndex;
	I2CPtr->I2CPutBits			= LgI2CPutBits;
	I2CPtr->I2CGetBits			= LgI2CGetBits;
	I2CPtr->DriverPrivate.ptr	= pCir;

	if (!xf86I2CBusInit(I2CPtr))
		return FALSE;

	I2CPtr = xf86CreateI2CBusRec();
	if (!I2CPtr) return FALSE;

	pCir->I2CPtr2 = I2CPtr;

	I2CPtr->BusName				= "I2C bus 2";
	I2CPtr->scrnIndex			= pScrn->scrnIndex;
	I2CPtr->I2CPutBits			= LgI2CPutBits;
	I2CPtr->I2CGetBits			= LgI2CGetBits;
	I2CPtr->DriverPrivate.ptr	= pCir;

	if (!xf86I2CBusInit(I2CPtr))
		return FALSE;

	return TRUE;
}
Exemple #18
0
Bool
LgXAAInit(ScreenPtr pScreen)
{
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    CirPtr pCir = CIRPTR(pScrn);
    XAAInfoRecPtr XAAPtr;

	XAAPtr = XAACreateInfoRec();
	if (!XAAPtr)
		return FALSE;

	/*
	 * Solid color fills.
	 */
	XAAPtr->SetupForSolidFill = LgSetupForSolidFill;
	XAAPtr->SubsequentSolidFillRect = LgSubsequentSolidFillRect;
	XAAPtr->SubsequentSolidFillTrap = NULL;
	XAAPtr->SolidFillFlags = 0;

	/*
	 * Screen-to-screen copies.
	 */
	XAAPtr->SetupForScreenToScreenCopy = LgSetupForScreenToScreenCopy;
	XAAPtr->SubsequentScreenToScreenCopy = LgSubsequentScreenToScreenCopy;
	/* Maybe ONLY_LEFT_TO_RIGHT_BITBLT or ONLY_TWO_BITBLT_DIRECTIONS? */
	XAAPtr->ScreenToScreenCopyFlags = ONLY_LEFT_TO_RIGHT_BITBLT;

	/*
	 * Miscellany.
	 */
	XAAPtr->Sync = LgSync;

	pCir->AccelInfoRec = XAAPtr;

	if (!XAAInit(pScreen, XAAPtr))
		return FALSE;

	return TRUE;
}
static Bool 
AlpPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap,
	       int xdir, int ydir, int alu, Pixel planemask)
{
    ScreenPtr pScreen = pSrcPixmap->drawable.pScreen;
    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
    CirPtr pCir = CIRPTR(pScrn);
    int pitch = pCir->pitch;

#ifdef ALP_DEBUG
    ErrorF("AlpPrepareCopy xdir=%d ydir=%d alu=%x planemask=%x\n",
	   xdir, ydir, alu, planemask);
#endif
    WAIT;
    SetupForRop(alu);
    /* Set dest pitch */
    outw(pCir->PIOReg, ((pitch << 8) & 0xff00) | 0x24);
    outw(pCir->PIOReg, ((pitch) & 0x1f00) | 0x25);
    /* Set source pitch */
    outw(pCir->PIOReg, ((pitch << 8) & 0xff00) | 0x26);
    outw(pCir->PIOReg, ((pitch) & 0x1f00) | 0x27);
    return TRUE;
}
Exemple #20
0
static void
LgSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
				int rop, unsigned int planemask, int transparency_color)
{
	int bltmode = 0;
	const CirPtr pCir = CIRPTR(pScrn);
	const LgPtr pLg = LGPTR(pCir);

	pLg->blitTransparent = (transparency_color != -1);
	pLg->blitYDir = ydir;

	LgWaitQAvail(pCir, 4);

	/* We set the rop up here because the LgSETROP macro conveniently
	   (really -- it is convenient!) clears the transparency bits
	   in DRAWDEF.  We'll set those bits appropriatly later. */
	LgSETROP(lgRop[rop]);

	if (ydir < 0)
		bltmode |= BLITUP;
	if (pLg->blitTransparent) {
		/* Gotta extend the transparency_color to the full 32-bit
		   size of the register. */
		transparency_color = LgExpandColor(transparency_color,
										   pScrn->bitsPerPixel);

		bltmode |= COLORTRANS;
		LgSETBACKGROUND(transparency_color);
		LgSETTRANSPARENCY(TRANSEQ);
	} else {
		LgSETTRANSPARENCY(TRANSNONE);
	}

	LgSETMODE(SCR2SCR | COLORSRC | bltmode);
	LgSetBitmask(pCir, planemask);
}
/* 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;
}