#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86_ansic.h"
#include "compiler.h"
#include "xf86Pci.h"
#include "xf86PciInfo.h"
#include "xaa.h"
#include "vgaHW.h"
#include "xf86xv.h"
#include "i740.h"
static unsigned int i740Rop[16] = {
0x00,
0x88,
0x44,
0xCC,
0x22,
0xAA,
0x66,
0xEE,
0x11,
0x99,
0x55,
0xDD,
0x33,
0xBB,
0x77,
0xFF
};
static unsigned int i740PatternRop[16] = {
0x00,
0xA0,
0x50,
0xF0,
0x0A,
0xAA,
0x5A,
0xFA,
0x05,
0xA5,
0x55,
0xF5,
0x0F,
0xAF,
0x5F,
0xFF
};
static void I740SyncPIO(ScrnInfoPtr pScrn);
static void I740SyncMMIO(ScrnInfoPtr pScrn);
static void I740SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
unsigned int planemask);
static void I740SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y,
int w, int h);
static void I740SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
int ydir, int rop,
unsigned int planemask,
int transparency_color);
static void I740SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
int x2, int y2, int w, int h);
static void I740SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
int pattx, int patty,
int fg, int bg, int rop,
unsigned int planemask);
static void I740SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
int pattx, int patty,
int x, int y, int w, int h);
#if 0
static void I740SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
int bg, int fg, int rop,
unsigned int planemask);
static void I740SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
int x, int y, int w, int h,
int skipleft);
#endif
Bool
I740AccelInit(ScreenPtr pScreen) {
XAAInfoRecPtr infoPtr;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I740Ptr pI740 = I740PTR(pScrn);
pI740->AccelInfoRec = infoPtr = XAACreateInfoRec();
if (!infoPtr) return FALSE;
if (pScrn->bitsPerPixel == 32) {
infoPtr->Flags = 0;
return TRUE;;
}
infoPtr->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER;
if (pI740->usePIO)
infoPtr->Sync = I740SyncPIO;
else
infoPtr->Sync = I740SyncMMIO;
infoPtr->CachePixelGranularity=8/pI740->cpp;
infoPtr->SolidFillFlags = NO_PLANEMASK;
infoPtr->SetupForSolidFill = I740SetupForSolidFill;
infoPtr->SubsequentSolidFillRect = I740SubsequentSolidFillRect;
infoPtr->ScreenToScreenCopyFlags = (NO_PLANEMASK | NO_TRANSPARENCY);
infoPtr->SetupForScreenToScreenCopy = I740SetupForScreenToScreenCopy;
infoPtr->SubsequentScreenToScreenCopy = I740SubsequentScreenToScreenCopy;
infoPtr->SetupForMono8x8PatternFill = I740SetupForMono8x8PatternFill;
infoPtr->SubsequentMono8x8PatternFillRect = I740SubsequentMono8x8PatternFillRect;
infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | HARDWARE_PATTERN_SCREEN_ORIGIN |
BIT_ORDER_IN_BYTE_MSBFIRST;
#if 0
#ifndef ALLOW_PCI_COLOR_EXP
if (pI740->Chipset != PCI_CHIP_I740_PCI) {
#endif
infoPtr->CPUToScreenColorExpandFillFlags =
NO_PLANEMASK |
#ifdef USE_DWORD_COLOR_EXP
SCANLINE_PAD_DWORD |
#endif
CPU_TRANSFER_PAD_QWORD |
SYNC_AFTER_COLOR_EXPAND |
BIT_ORDER_IN_BYTE_MSBFIRST;
infoPtr->ColorExpandBase = (unsigned char *)(pI740->MMIOBase + BLTDATA);
infoPtr->ColorExpandRange = 0x10000;
infoPtr->SetupForCPUToScreenColorExpandFill = I740SetupForCPUToScreenColorExpandFill;
infoPtr->SubsequentCPUToScreenColorExpandFill = I740SubsequentCPUToScreenColorExpandFill;
#ifndef ALLOW_PCI_COLOR_EXP
}
#endif
#endif
return XAAInit(pScreen, infoPtr);
}
static void
I740SyncPIO(ScrnInfoPtr pScrn) {
WAIT_ENGINE_IDLE_PIO();
}
static void
I740SyncMMIO(ScrnInfoPtr pScrn) {
I740Ptr pI740;
pI740 = I740PTR(pScrn);
WAIT_ENGINE_IDLE_MMIO();
}
static void
I740SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
unsigned int planemask) {
I740Ptr pI740;
pI740 = I740PTR(pScrn);
pI740->bltcmd.BR00 = ((pScrn->displayWidth * pI740->cpp) << 16) |
(pScrn->displayWidth * pI740->cpp);
pI740->bltcmd.BR01 = color;
pI740->bltcmd.BR04 = SOLID_PAT_SELECT | PAT_IS_MONO | i740PatternRop[rop];
}
static void
I740SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) {
I740Ptr pI740;
pI740 = I740PTR(pScrn);
WAIT_LP_FIFO(12);
OUTREG(LP_FIFO, 0x6000000A);
OUTREG(LP_FIFO, pI740->bltcmd.BR00);
OUTREG(LP_FIFO, pI740->bltcmd.BR01);
OUTREG(LP_FIFO, 0x00000000);
OUTREG(LP_FIFO, 0x00000000);
OUTREG(LP_FIFO, pI740->bltcmd.BR04);
OUTREG(LP_FIFO, 0x00000000);
OUTREG(LP_FIFO, 0x00000000);
OUTREG(LP_FIFO, (y * pScrn->displayWidth + x) * pI740->cpp);
OUTREG(LP_FIFO, 0x00000000);
OUTREG(LP_FIFO, 0x00000000);
OUTREG(LP_FIFO, (h << 16) | (w * pI740->cpp));
}
static void
I740SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
unsigned int planemask, int transparency_color)
{
I740Ptr pI740;
pI740 = I740PTR(pScrn);
pI740->bltcmd.BR00 = (((pScrn->displayWidth * pI740->cpp) << 16) |
(pScrn->displayWidth * pI740->cpp));
pI740->bltcmd.BR04 = SRC_IS_IN_COLOR | SRC_USE_SRC_ADDR | i740Rop[rop];
if (xdir == -1)
pI740->bltcmd.BR04 |= BLT_RIGHT_TO_LEFT;
else
pI740->bltcmd.BR04 |= BLT_LEFT_TO_RIGHT;
if (ydir == -1)
pI740->bltcmd.BR04 |= BLT_BOT_TO_TOP;
else
pI740->bltcmd.BR04 |= BLT_TOP_TO_BOT;
pI740->bltcmd.BR01 = 0x00000000;
}
static void
I740SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
int x2, int y2, int w, int h) {
I740Ptr pI740;
pI740 = I740PTR(pScrn);
if (pI740->bltcmd.BR04 & BLT_BOT_TO_TOP) {
pI740->bltcmd.BR06 = (y1 + h - 1) *
pScrn->displayWidth * pI740->cpp;
pI740->bltcmd.BR07 = (y2 + h - 1) *
pScrn->displayWidth * pI740->cpp;
} else {
pI740->bltcmd.BR06 = y1 * pScrn->displayWidth * pI740->cpp;
pI740->bltcmd.BR07 = y2 * pScrn->displayWidth * pI740->cpp;
}
if (pI740->bltcmd.BR04 & BLT_RIGHT_TO_LEFT) {
pI740->bltcmd.BR06 += (x1 + w - 1) * pI740->cpp + pI740->cpp - 1;
pI740->bltcmd.BR07 += (x2 + w - 1) * pI740->cpp + pI740->cpp - 1;
} else {
pI740->bltcmd.BR06 += x1 * pI740->cpp;
pI740->bltcmd.BR07 += x2 * pI740->cpp;
}
WAIT_LP_FIFO(12);
OUTREG(LP_FIFO, 0x6000000A);
OUTREG(LP_FIFO, pI740->bltcmd.BR00);
OUTREG(LP_FIFO, pI740->bltcmd.BR01);
OUTREG(LP_FIFO, 0x00000000);
OUTREG(LP_FIFO, 0x00000000);
OUTREG(LP_FIFO, pI740->bltcmd.BR04);
OUTREG(LP_FIFO, 0x00000000);
OUTREG(LP_FIFO, pI740->bltcmd.BR06);
OUTREG(LP_FIFO, pI740->bltcmd.BR07);
OUTREG(LP_FIFO, 0x00000000);
OUTREG(LP_FIFO, 0x00000000);
OUTREG(LP_FIFO, (h << 16) | (w * pI740->cpp));
}
static void
I740SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty,
int fg, int bg, int rop,
unsigned int planemask) {
I740Ptr pI740;
pI740 = I740PTR(pScrn);
pI740->bltcmd.BR00 = ((pScrn->displayWidth * pI740->cpp) << 16) |
(pScrn->displayWidth * pI740->cpp);
pI740->bltcmd.BR01 = bg;
pI740->bltcmd.BR02 = fg;
pI740->bltcmd.BR04 = PAT_IS_MONO | i740PatternRop[rop];
if (bg == -1) pI740->bltcmd.BR04 |= MONO_PAT_TRANSP;
pI740->bltcmd.BR05 = (pattx + patty * pScrn->displayWidth) * pI740->cpp;
}
static void
I740SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty,
int x, int y, int w, int h) {
I740Ptr pI740;
pI740 = I740PTR(pScrn);
WAIT_LP_FIFO(12);
OUTREG(LP_FIFO, 0x6000000A);
OUTREG(LP_FIFO, pI740->bltcmd.BR00);
OUTREG(LP_FIFO, pI740->bltcmd.BR01);
OUTREG(LP_FIFO, pI740->bltcmd.BR02);
OUTREG(LP_FIFO, 0x00000000);
OUTREG(LP_FIFO, pI740->bltcmd.BR04 | ((y<<20) & PAT_VERT_ALIGN));
OUTREG(LP_FIFO, pI740->bltcmd.BR05);
OUTREG(LP_FIFO, 0x00000000);
OUTREG(LP_FIFO, (y * pScrn->displayWidth + x) * pI740->cpp);
OUTREG(LP_FIFO, 0x00000000);
OUTREG(LP_FIFO, 0x00000000);
OUTREG(LP_FIFO, (h << 16) | (w * pI740->cpp));
}
#if 0
static void
I740SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int bg, int fg,
int rop, unsigned int planemask) {
I740Ptr pI740;
pI740 = I740PTR(pScrn);
pI740->bltcmd.BR00 = (pScrn->displayWidth * pI740->cpp) << 16;
pI740->bltcmd.BR01 = bg;
pI740->bltcmd.BR02 = fg;
#ifdef USE_DWORD_COLOR_EXP
pI740->bltcmd.BR03 = MONO_DWORD_ALIGN | MONO_USE_COLEXP;
#else
pI740->bltcmd.BR03 = MONO_BIT_ALIGN | MONO_USE_COLEXP;
#endif
pI740->bltcmd.BR04 = SRC_IS_MONO | SRC_USE_BLTDATA | i740Rop[rop];
if (bg == -1) pI740->bltcmd.BR04 |= MONO_SRC_TRANSP;
}
static void
I740SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, int y,
int w, int h, int skipleft) {
I740Ptr pI740;
pI740 = I740PTR(pScrn);
pI740->AccelInfoRec->Sync(pScrn);
OUTREG(LP_FIFO, 0x6000000A);
OUTREG(LP_FIFO, pI740->bltcmd.BR00);
OUTREG(LP_FIFO, pI740->bltcmd.BR01);
OUTREG(LP_FIFO, pI740->bltcmd.BR02);
OUTREG(LP_FIFO, pI740->bltcmd.BR03 | (skipleft & MONO_SRC_LEFT_CLIP));
OUTREG(LP_FIFO, pI740->bltcmd.BR04);
OUTREG(LP_FIFO, 0x00000000);
OUTREG(LP_FIFO, 0x00000000);
OUTREG(LP_FIFO, (y * pScrn->displayWidth + x) * pI740->cpp);
OUTREG(LP_FIFO, 0x00000000);
OUTREG(LP_FIFO, 0x00000000);
#ifdef USE_DWORD_COLOR_EXP
WAIT_BLT_IDLE();
#endif
OUTREG(LP_FIFO, (h << 16) | (w * pI740->cpp));
}
#endif