#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86_ansic.h"
#include "compiler.h"
#include "xf86fbman.h"
#include "miline.h"
#include "neo.h"
#include "neo_reg.h"
#include "neo_macros.h"
#define NEO2070_BLTSTAT 0x00
#define NEO2070_BLTCNTL 0x04
#define NEO2070_XPCOLOR 0x08
#define NEO2070_FGCOLOR 0x0c
#define NEO2070_BGCOLOR 0x10
#define NEO2070_PLANEMASK 0x14
#define NEO2070_XYEXT 0x18
#define NEO2070_SRCPITCH 0x1c
#define NEO2070_SRCBITOFF 0x20
#define NEO2070_SRCSTART 0x24
#define NEO2070_DSTPITCH 0x28
#define NEO2070_DSTBITOFF 0x2c
#define NEO2070_DSTSTART 0x30
static unsigned int neo2070Rop[16] = {
0x000000,
0x080000,
0x040000,
0x0c0000,
0x020000,
0x0a0000,
0x060000,
0x0e0000,
0x010000,
0x090000,
0x050000,
0x0d0000,
0x030000,
0x0b0000,
0x070000,
0x0f0000
};
static void Neo2070Sync(ScrnInfoPtr pScrn);
static void Neo2070SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
int ydir, int rop,
unsigned int planemask,
int trans_color);
static void Neo2070SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX,
int srcY, int dstX, int dstY,
int w, int h);
static void Neo2070SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop,
unsigned int planemask);
static void Neo2070SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y,
int w, int h);
Bool
Neo2070AccelInit(ScreenPtr pScreen)
{
XAAInfoRecPtr infoPtr;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
NEOPtr nPtr = NEOPTR(pScrn);
NEOACLPtr nAcl = NEOACLPTR(pScrn);
nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec();
if(!infoPtr) return FALSE;
infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS;
if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags |= PIXMAP_CACHE;
#if 0
infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES;
#endif
infoPtr->Sync = Neo2070Sync;
infoPtr->ScreenToScreenCopyFlags = (NO_TRANSPARENCY | GXCOPY_ONLY);
infoPtr->SetupForScreenToScreenCopy =
Neo2070SetupForScreenToScreenCopy;
infoPtr->SubsequentScreenToScreenCopy =
Neo2070SubsequentScreenToScreenCopy;
infoPtr->SolidFillFlags = GXCOPY_ONLY;
infoPtr->SetupForSolidFill =
Neo2070SetupForSolidFillRect;
infoPtr->SubsequentSolidFillRect =
Neo2070SubsequentSolidFillRect;
switch (pScrn->bitsPerPixel) {
case 8:
nAcl->BltCntlFlags = NEO_BC1_DEPTH8;
nAcl->ColorShiftAmt = 8;
nAcl->PixelWidth = 1;
nAcl->PlaneMask = 0xff;
break;
case 15:
case 16:
nAcl->BltCntlFlags = NEO_BC1_DEPTH16;
nAcl->ColorShiftAmt = 0;
nAcl->PixelWidth = 2;
nAcl->PlaneMask = 0xffff;
break;
case 24:
default:
return FALSE;
}
return(XAAInit(pScreen, infoPtr));
}
static void
Neo2070Sync(ScrnInfoPtr pScrn)
{
NEOPtr nPtr = NEOPTR(pScrn);
WAIT_ENGINE_IDLE();
}
static void
Neo2070SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
int rop,
unsigned int planemask,
int trans_color)
{
NEOPtr nPtr = NEOPTR(pScrn);
NEOACLPtr nAcl = NEOACLPTR(pScrn);
WAIT_ENGINE_IDLE();
OUTREG(NEO2070_BLTCNTL, nAcl->tmpBltCntlFlags);
OUTREG(NEO2070_PLANEMASK, planemask |= (planemask << nAcl->ColorShiftAmt));
OUTREG(NEO2070_SRCPITCH, nAcl->Pitch);
OUTREG(NEO2070_DSTPITCH, nAcl->Pitch);
OUTREG(NEO2070_SRCBITOFF, 0);
OUTREG(NEO2070_DSTBITOFF, 0);
}
static void
Neo2070SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
int srcX, int srcY,
int dstX, int dstY,
int w, int h)
{
NEOPtr nPtr = NEOPTR(pScrn);
NEOACLPtr nAcl = NEOACLPTR(pScrn);
if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) {
WAIT_ENGINE_IDLE();
OUTREG(NEO2070_BLTCNTL, nAcl->tmpBltCntlFlags);
OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff));
OUTREG(NEO2070_SRCSTART,
(srcY * nAcl->Pitch) + (srcX * nAcl->PixelWidth));
OUTREG(NEO2070_DSTSTART,
(dstY * nAcl->Pitch) + (dstX * nAcl->PixelWidth));
}
else {
WAIT_ENGINE_IDLE();
OUTREG(NEO2070_BLTCNTL, (nAcl->tmpBltCntlFlags | NEO_BC0_X_DEC
| NEO_BC0_DST_Y_DEC
| NEO_BC0_SRC_Y_DEC));
OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff));
OUTREG(NEO2070_SRCSTART,
((srcY+h-1) * nAcl->Pitch) + ((srcX+w-1) * nAcl->PixelWidth));
OUTREG(NEO2070_DSTSTART,
((dstY+h-1) * nAcl->Pitch) + ((dstX+w-1) * nAcl->PixelWidth));
}
}
static void
Neo2070SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop,
unsigned int planemask)
{
NEOPtr nPtr = NEOPTR(pScrn);
NEOACLPtr nAcl = NEOACLPTR(pScrn);
planemask &= nAcl->PlaneMask;
if (!rop) color=0;
WAIT_ENGINE_IDLE();
OUTREG(NEO2070_BLTCNTL, nAcl->BltCntlFlags |
NEO_BC0_SRC_IS_FG | neo2070Rop[3]);
OUTREG(NEO2070_PLANEMASK, planemask |= (planemask << nAcl->ColorShiftAmt));
if (pScrn->bitsPerPixel == 8)
OUTREG(NEO2070_FGCOLOR, color |= (color << 8));
else
OUTREG(NEO2070_FGCOLOR, ((color&0xff00) >> 8) | (color << 8));
OUTREG(NEO2070_SRCPITCH, nAcl->Pitch);
OUTREG(NEO2070_DSTPITCH, nAcl->Pitch);
OUTREG(NEO2070_SRCBITOFF, 0);
OUTREG(NEO2070_DSTBITOFF, 0);
}
static void
Neo2070SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
{
NEOPtr nPtr = NEOPTR(pScrn);
NEOACLPtr nAcl = NEOACLPTR(pScrn);
WAIT_ENGINE_IDLE();
OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff));
OUTREG(NEO2070_DSTSTART, (y * nAcl->Pitch) + (x * nAcl->PixelWidth));
}