mirror of
https://github.com/X11Libre/xf86-video-cirrus.git
synced 2026-03-24 01:24:45 +00:00
this fixes cirrus to work with a server with no XAA module. Signed-off-by: Dave Airlie <airlied@redhat.com>
271 lines
6.5 KiB
C
271 lines
6.5 KiB
C
/* (c) Itai Nahshon */
|
|
/* #define DEBUG */
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include "xf86.h"
|
|
#include "xf86_OSproc.h"
|
|
#include "compiler.h"
|
|
|
|
#include "xf86Pci.h"
|
|
|
|
#include "vgaHW.h"
|
|
|
|
#include "cir.h"
|
|
#define _ALP_PRIVATE_
|
|
#include "alp.h"
|
|
|
|
#ifdef HAVE_XAA_H
|
|
#ifdef DEBUG
|
|
#define minb(p) \
|
|
(ErrorF("minb(%X)\n", p),\
|
|
MMIO_IN8(pCir->chip.alp->BLTBase, (p)))
|
|
#define moutb(p,v) \
|
|
(ErrorF("moutb(%X, %X)\n", p,v),\
|
|
MMIO_OUT8(pCir->chip.alp->BLTBase, (p),(v)))
|
|
#define vga_minb(p) \
|
|
(ErrorF("minb(%X)\n", p),\
|
|
MMIO_IN8(hwp->MMIOBase, (hwp->MMIOOffset + (p))))
|
|
#define vga_moutb(p,v) \
|
|
{ ErrorF("moutb(%X, %X)\n", p,v);\
|
|
MMIO_OUT8(hwp->MMIOBase, (hwp->MMIOOffset + (p)),(v));}
|
|
#define minl(p) \
|
|
(ErrorF("minl(%X)\n", p),\
|
|
MMIO_IN32(pCir->chip.alp->BLTBase, (p)))
|
|
#define moutl(p,v) \
|
|
(ErrorF("moutl(%X, %X)\n", p,v),\
|
|
MMIO_OUT32(pCir->chip.alp->BLTBase, (p),(v)))
|
|
#else
|
|
#define minb(p) MMIO_IN8(pCir->chip.alp->BLTBase, (p))
|
|
#define moutb(p,v) MMIO_OUT8(pCir->chip.alp->BLTBase, (p),(v))
|
|
#define vga_minb(p) MMIO_IN8(hwp->MMIIOBase, (hwp->MMIOOffset + (p)))
|
|
#define vga_moutb(p,v) MMIO_OUT8(hwp->MMIOBase, (hwp->MMIOOffset + (p)),(v))
|
|
#define minl(p) MMIO_IN32(pCir->chip.alp->BLTBase, (p))
|
|
#define moutl(p,v) MMIO_OUT32(pCir->chip.alp->BLTBase, (p),(v))
|
|
#endif
|
|
|
|
static const CARD8 translated_rop[] =
|
|
{
|
|
/* GXclear */ 0x00U,
|
|
/* GXand */ 0x05U,
|
|
/* GXandreverse */ 0x09U,
|
|
/* GXcopy */ 0x0DU,
|
|
/* GXandinversted */ 0x50U,
|
|
/* GXnoop */ 0x06U,
|
|
/* GXxor */ 0x59U,
|
|
/* GXor */ 0x6DU,
|
|
/* GXnor */ 0x90U,
|
|
/* GXequiv */ 0x95U,
|
|
/* GXinvert */ 0x0BU,
|
|
/* GXorReverse */ 0xADU,
|
|
/* GXcopyInverted */ 0xD0U,
|
|
/* GXorInverted */ 0xD6U,
|
|
/* GXnand */ 0xDAU,
|
|
/* GXset */ 0x0EU
|
|
};
|
|
|
|
#define WAIT while(minl(0x40) & pCir->chip.alp->waitMsk){};
|
|
#define WAIT_1 while((minl(0x40)) & 0x1){};
|
|
|
|
static void AlpSync(ScrnInfoPtr pScrn)
|
|
{
|
|
CirPtr pCir = CIRPTR(pScrn);
|
|
#ifdef ALP_DEBUG
|
|
ErrorF("AlpSync mm\n");
|
|
#endif
|
|
WAIT_1;
|
|
return;
|
|
}
|
|
|
|
static void
|
|
AlpSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
|
|
unsigned int planemask, int trans_color)
|
|
{
|
|
CirPtr pCir = CIRPTR(pScrn);
|
|
int pitch = pCir->pitch;
|
|
|
|
WAIT;
|
|
|
|
pCir->chip.alp->transRop = translated_rop[rop] << 16;
|
|
|
|
#ifdef ALP_DEBUG
|
|
ErrorF("AlpSetupForScreenToScreenCopy xdir=%d ydir=%d rop=%x planemask=%x trans_color=%x\n",
|
|
xdir, ydir, rop, planemask, trans_color);
|
|
#endif
|
|
moutl(0x0C, (pitch << 16) | pitch);
|
|
|
|
}
|
|
|
|
static void
|
|
AlpSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2,
|
|
int y2, int w, int h)
|
|
{
|
|
CirPtr pCir = CIRPTR(pScrn);
|
|
int source, dest;
|
|
int hh, ww;
|
|
int decrement = 0;
|
|
int pitch = pCir->pitch;
|
|
|
|
ww = ((w * pScrn->bitsPerPixel / 8) - 1) & 0x1fff;
|
|
hh = (h - 1) & 0x1fff;
|
|
dest = y2 * pitch + x2 * pScrn->bitsPerPixel / 8;
|
|
source = y1 * pitch + x1 * pScrn->bitsPerPixel / 8;
|
|
if (dest > source) {
|
|
decrement = 1;
|
|
dest += hh * pitch + ww;
|
|
source += hh * pitch + ww;
|
|
}
|
|
|
|
WAIT;
|
|
|
|
/* Width / Height */
|
|
moutl(0x08, (hh << 16) | ww);
|
|
/* source */
|
|
moutl(0x14, source & 0x3fffff);
|
|
moutl(0x18, pCir->chip.alp->transRop | decrement);
|
|
|
|
/* dest */
|
|
write_mem_barrier();
|
|
moutl(0x10, dest & 0x3fffff);
|
|
|
|
#ifdef ALP_DEBUG
|
|
ErrorF("AlpSubsequentScreenToScreenCopy x1=%d y1=%d x2=%d y2=%d w=%d h=%d\n",
|
|
x1, y1, x2, y2, w, h);
|
|
ErrorF("AlpSubsequentScreenToScreenCopy s=%d d=%d ww=%d hh=%d\n",
|
|
source, dest, ww, hh);
|
|
#endif
|
|
if (!pCir->chip.alp->autoStart) {
|
|
CARD32 val = minl(0x40);
|
|
moutl(0x40,val | 0x02);
|
|
}
|
|
write_mem_barrier();
|
|
}
|
|
|
|
|
|
static void
|
|
AlpSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
|
|
unsigned int planemask)
|
|
{
|
|
CirPtr pCir = CIRPTR(pScrn);
|
|
int pitch = pCir->pitch;
|
|
|
|
WAIT;
|
|
|
|
#ifdef ALP_DEBUG
|
|
ErrorF("AlpSetupForSolidFill color=%x rop=%x planemask=%x\n",
|
|
color, rop, planemask);
|
|
#endif
|
|
|
|
moutl(0x04, color & 0xffffff);
|
|
|
|
/* Set dest pitch */
|
|
moutl(0x0C, pitch & 0x1fff);
|
|
moutl(0x18, (((pScrn->bitsPerPixel - 8) << 1))
|
|
| translated_rop[rop] << 16
|
|
| 0x040000C0);
|
|
}
|
|
|
|
static void
|
|
AlpSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
|
|
{
|
|
int dest;
|
|
int hh, ww;
|
|
CirPtr pCir = CIRPTR(pScrn);
|
|
int pitch = pCir->pitch;
|
|
|
|
ww = ((w * pScrn->bitsPerPixel / 8) - 1) & 0x1fff;
|
|
hh = (h - 1) & 0x7ff;
|
|
dest = y * pitch + x * pScrn->bitsPerPixel / 8;
|
|
|
|
WAIT;
|
|
|
|
/* Width / Height */
|
|
write_mem_barrier();
|
|
moutl(0x08, (hh << 16) | ww);
|
|
|
|
#ifdef ALP_DEBUG
|
|
ErrorF("AlpSubsequentSolidFillRect x=%d y=%d w=%d h=%d\n",
|
|
x, y, w, h);
|
|
#endif
|
|
/* dest */
|
|
moutl(0x10, (dest & 0x3fffff));
|
|
|
|
if (!pCir->chip.alp->autoStart) {
|
|
CARD32 val = minl(0x40);
|
|
moutl(0x40, val | 0x02);
|
|
}
|
|
write_mem_barrier();
|
|
}
|
|
|
|
static void
|
|
AlpAccelEngineInit(ScrnInfoPtr pScrn)
|
|
{
|
|
vgaHWPtr hwp = VGAHWPTR(pScrn);
|
|
CirPtr pCir = CIRPTR(pScrn);
|
|
|
|
if (pCir->Chipset != PCI_CHIP_GD7548) {
|
|
vga_moutb(0x3CE, 0x0E); /* enable writes to gr33 */
|
|
vga_moutb(0x3CF, 0x20); /* enable writes to gr33 */
|
|
}
|
|
if (pCir->properties & ACCEL_AUTOSTART) {
|
|
moutl(0x40, 0x80); /* enable autostart */
|
|
pCir->chip.alp->waitMsk = 0x10;
|
|
pCir->chip.alp->autoStart = TRUE;
|
|
} else {
|
|
pCir->chip.alp->waitMsk = 0x1;
|
|
pCir->chip.alp->autoStart = FALSE;
|
|
}
|
|
}
|
|
|
|
Bool
|
|
AlpXAAInitMMIO(ScreenPtr pScreen)
|
|
{
|
|
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
|
|
CirPtr pCir = CIRPTR(pScrn);
|
|
XAAInfoRecPtr XAAPtr;
|
|
|
|
pCir->InitAccel = AlpAccelEngineInit;
|
|
#ifdef ALP_DEBUG
|
|
ErrorF("AlpXAAInitMM\n");
|
|
#endif
|
|
|
|
XAAPtr = XAACreateInfoRec();
|
|
if (!XAAPtr) return FALSE;
|
|
|
|
XAAPtr->Flags |= LINEAR_FRAMEBUFFER;
|
|
XAAPtr->Sync = AlpSync;
|
|
|
|
XAAPtr->SetupForScreenToScreenCopy = AlpSetupForScreenToScreenCopy;
|
|
XAAPtr->SubsequentScreenToScreenCopy = AlpSubsequentScreenToScreenCopy;
|
|
XAAPtr->ScreenToScreenCopyFlags =
|
|
(NO_TRANSPARENCY | NO_PLANEMASK);
|
|
|
|
XAAPtr->SetupForSolidFill = AlpSetupForSolidFill;
|
|
XAAPtr->SubsequentSolidFillRect = AlpSubsequentSolidFillRect;
|
|
XAAPtr->SubsequentSolidFillTrap = NULL;
|
|
XAAPtr->SolidFillFlags = NO_PLANEMASK;
|
|
|
|
switch (pCir->Chipset) {
|
|
case PCI_CHIP_GD5480:
|
|
case PCI_CHIP_GD5446:
|
|
pCir->chip.alp->BLTBase = pCir->IOBase + 0x100;
|
|
break;
|
|
default:
|
|
pCir->chip.alp->BLTBase = pCir->IOBase;
|
|
break;
|
|
}
|
|
|
|
AlpAccelEngineInit(pScrn);
|
|
|
|
pCir->AccelInfoRec = XAAPtr;
|
|
|
|
if (!XAAInit(pScreen, XAAPtr))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#endif
|