Initial import of Permedia2 driver

This commit is contained in:
Carlos Romero 2004-05-24 19:31:41 +00:00
parent 5b2211ec35
commit 32d0920ef9
6 changed files with 2151 additions and 0 deletions

33
hw/kdrive/pm2/Makefile.am Normal file
View File

@ -0,0 +1,33 @@
INCLUDES = \
@KDRIVE_INCS@ \
-I$(top_srcdir)/hw/kdrive/vesa \
@XSERVER_CFLAGS@
bin_PROGRAMS = Xpm2
if TSLIB
TSLIB_FLAG = -lts
endif
noinst_LIBRARIES = libpm2.a
libpm2_a_SOURCES = \
glint_regs.h \
pm2.c \
pm2_draw.c \
pm2.h
Xpm2_SOURCES = \
pm2stub.c
PM2_LIBS = \
libpm2.a \
$(top_builddir)/hw/kdrive/vesa/libvesa.a \
@KDRIVE_LIBS@
Xpm2_LDADD = \
$(PM2_LIBS) \
@XSERVER_LIBS@ \
$(TSLIB_FLAG)
Xpm2_DEPENDENCIES = $(PM2_LIBS) @KDRIVE_LIBS@

1371
hw/kdrive/pm2/glint_regs.h Normal file

File diff suppressed because it is too large Load Diff

294
hw/kdrive/pm2/pm2.c Normal file
View File

@ -0,0 +1,294 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "kdrive.h"
#include "pm2.h"
#define PARTPROD(a,b,c) (((a)<<6) | ((b)<<3) | (c))
char bppand[4] = { 0x03, /* 8bpp */
0x01, /* 16bpp */
0x00, /* 24bpp */
0x00 /* 32bpp */};
int partprodPermedia[] = {
-1,
PARTPROD(0,0,1), PARTPROD(0,1,1), PARTPROD(1,1,1), PARTPROD(1,1,2),
PARTPROD(1,2,2), PARTPROD(2,2,2), PARTPROD(1,2,3), PARTPROD(2,2,3),
PARTPROD(1,3,3), PARTPROD(2,3,3), PARTPROD(1,2,4), PARTPROD(3,3,3),
PARTPROD(1,3,4), PARTPROD(2,3,4), -1, PARTPROD(3,3,4),
PARTPROD(1,4,4), PARTPROD(2,4,4), -1, PARTPROD(3,4,4),
-1, PARTPROD(2,3,5), -1, PARTPROD(4,4,4),
PARTPROD(1,4,5), PARTPROD(2,4,5), PARTPROD(3,4,5), -1,
-1, -1, -1, PARTPROD(4,4,5),
PARTPROD(1,5,5), PARTPROD(2,5,5), -1, PARTPROD(3,5,5),
-1, -1, -1, PARTPROD(4,5,5),
-1, -1, -1, PARTPROD(3,4,6),
-1, -1, -1, PARTPROD(5,5,5),
PARTPROD(1,5,6), PARTPROD(2,5,6), -1, PARTPROD(3,5,6),
-1, -1, -1, PARTPROD(4,5,6),
-1, -1, -1, -1,
-1, -1, -1, PARTPROD(5,5,6),
-1, -1, -1, -1,
-1, -1, -1, -1,
-1, -1, -1, -1,
-1, -1, -1, -1,
-1, -1, -1, -1,
-1, -1, -1, -1,
-1, -1, -1, -1,
-1, -1, -1, -1,
-1, -1, -1, -1,
-1, -1, -1, -1,
-1, -1, -1, -1,
-1, -1, -1, -1,
-1, -1, -1, -1,
-1, -1, -1, -1,
-1, -1, -1, -1,
-1, -1, -1, -1,
0};
Bool
pmMapReg(KdCardInfo *card, PM2CardInfo *pm2c)
{
pm2c->reg_base = (CARD8 *)KdMapDevice(PM2_REG_BASE(card),
PM2_REG_SIZE(card));
if (pm2c->reg_base == NULL)
return FALSE;
// pm2c->render = (PMRender *) (pm2c->reg_base + RENDER_UNIT);
// pm2c->rect = (PMRectangle *) (pm2c->reg_base + RECT_UNIT);
// pm2c->mode = (PMMode *) (pm2c->reg_base + MODE_UNIT);
// pm2c->color = (PMColor *) (pm2c->reg_base + COLOR_UNIT);
// pm2c->scissor = (PMScissor *) (pm2c->reg_base + SCISSOR_UNIT);
KdSetMappedMode(PM2_REG_BASE(card), PM2_REG_SIZE(card),
KD_MAPPED_MODE_REGISTERS);
return TRUE;
}
void
pmUnmapReg(KdCardInfo *card, PM2CardInfo *pm2c)
{
if (pm2c->reg_base) {
KdResetMappedMode(PM2_REG_BASE(card), PM2_REG_SIZE(card),
KD_MAPPED_MODE_REGISTERS);
KdUnmapDevice((void *)pm2c->reg_base, PM2_REG_SIZE(card));
pm2c->reg_base = 0;
}
}
Bool
pmCardInit (KdCardInfo *card)
{
int i;
PM2CardInfo *pm2c;
pm2c = (PM2CardInfo *) xalloc (sizeof (PM2CardInfo));
if (!pm2c)
return FALSE;
memset (pm2c, '\0', sizeof (PM2CardInfo));
(void) pmMapReg (card, pm2c);
if (!vesaInitialize (card, &pm2c->vesa))
{
xfree (pm2c);
return FALSE;
}
card->driver = pm2c;
return TRUE;
}
void
pmCardFini (KdCardInfo *card)
{
PM2CardInfo *pm2c = (PM2CardInfo *) card->driver;
pmUnmapReg (card, pm2c);
vesaCardFini (card);
}
Bool
pmScreenInit (KdScreenInfo *screen)
{
PM2CardInfo *pm2c = screen->card->driver;
PM2ScreenInfo *pm2s;
int screen_size, memory;
pm2s = (PM2ScreenInfo *) xalloc (sizeof (PM2ScreenInfo));
if (!pm2s)
return FALSE;
memset (pm2s, '\0', sizeof (PM2ScreenInfo));
if (!vesaScreenInitialize (screen, &pm2s->vesa))
{
xfree (pm2s);
return FALSE;
}
pm2c->pprod = partprodPermedia[screen->width >> 5];
pm2c->bppalign = bppand[(screen->fb[0].bitsPerPixel>>3)-1];
pm2s->screen = pm2s->vesa.fb;
memory = pm2s->vesa.fb_size;
screen_size = screen->fb[0].byteStride * screen->height;
if (pm2s->screen && memory >= screen_size + 2048)
{
memory -= 2048;
pm2s->cursor_base = pm2s->screen + memory - 2048;
}
else
pm2s->cursor_base = 0;
memory -= screen_size;
if (memory > screen->fb[0].byteStride)
{
pm2s->off_screen = pm2s->screen + screen_size;
pm2s->off_screen_size = memory;
}
else
{
pm2s->off_screen = 0;
pm2s->off_screen_size = 0;
}
screen->driver = pm2s;
return TRUE;
}
void
pmScreenFini (KdScreenInfo *screen)
{
PM2ScreenInfo *pm2s = (PM2ScreenInfo *) screen->driver;
vesaScreenFini (screen);
xfree (pm2s);
screen->driver = 0;
}
Bool
pmInitScreen (ScreenPtr pScreen)
{
return vesaInitScreen (pScreen);
}
#ifdef RANDR
static Bool
pmRandRSetConfig (ScreenPtr pScreen,
Rotation rotation,
int rate,
RRScreenSizePtr pSize)
{
KdCheckSync (pScreen);
if (!vesaRandRSetConfig (pScreen, rotation, rate, pSize))
return FALSE;
return TRUE;
}
static void
pmRandRInit (ScreenPtr pScreen)
{
rrScrPriv(pScreen);
pScrPriv->rrSetConfig = pmRandRSetConfig;
}
#endif
Bool
pmFinishInitScreen (ScreenPtr pScreen)
{
Bool ret;
ret = vesaFinishInitScreen (pScreen);
#ifdef RANDR
pmRandRInit (pScreen);
#endif
return ret;
}
void
pmPreserve(KdCardInfo *card)
{
vesaPreserve(card);
}
static void
pmRestore(KdCardInfo *card)
{
PM2CardInfo *pm2c = card->driver;
vesaRestore (card);
}
Bool
pmEnable (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
PM2CardInfo *pm2c = pScreenPriv->card->driver;
if (!vesaEnable (pScreen))
return FALSE;
#ifdef XV
KdXVEnable (pScreen);
#endif
return TRUE;
}
void
pmDisable(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
PM2CardInfo *pm2c = pScreenPriv->card->driver;
#ifdef XV
KdXVDisable (pScreen);
#endif
vesaDisable (pScreen);
}
static Bool
pmDPMS(ScreenPtr pScreen, int mode)
{
return vesaDPMS (pScreen, mode);
}
KdCardFuncs PM2Funcs = {
pmCardInit, /* cardinit */
pmScreenInit, /* scrinit */
pmInitScreen, /* initScreen */
pmFinishInitScreen, /* finishInitScreen */
vesaCreateResources, /* createRes */
pmPreserve, /* preserve */
pmEnable, /* enable */
pmDPMS, /* dpms */
pmDisable, /* disable */
pmRestore, /* restore */
pmScreenFini, /* scrfini */
pmCardFini, /* cardfini */
0, /* initCursor */
0, /* enableCursor */
0, /* disableCursor */
0, /* finiCursor */
NULL, /* recolorCursor */
pmDrawInit, /* initAccel */
pmDrawEnable, /* enableAccel */
pmDrawSync, /* syncAccel */
pmDrawDisable, /* disableAccel */
pmDrawFini, /* finiAccel */
vesaGetColors, /* getColors */
vesaPutColors, /* putColors */
};

184
hw/kdrive/pm2/pm2.h Normal file
View File

@ -0,0 +1,184 @@
#ifndef _PM2_H_
#define _PM2_H_
#include <vesa.h>
#include "kxv.h"
#include "klinux.h"
#include "glint_regs.h"
typedef volatile CARD8 VOL8;
typedef volatile CARD16 VOL16;
typedef volatile CARD32 VOL32;
#if 0
typedef struct {
VOL32 StartXDom;
VOL32 dXDom;
VOL32 StartXSub;
VOL32 dXSub;
VOL32 StartY;
VOL32 dY;
VOL32 GLINTCount;
VOL32 Render;
VOL32 ContinueNewLine;
VOL32 ContinueNewDom;
VOL32 ContinueNewSub;
VOL32 Continue;
VOL32 FlushSpan;
VOL32 BitMaskPattern;
} PMRender;
typedef struct {
VOL32 PointTable0;
VOL32 PointTable1;
VOL32 PointTable2;
VOL32 PointTable3;
VOL32 RasterizerMode;
VOL32 YLimits;
VOL32 ScanLineOwnership;
VOL32 WaitForCompletion;
VOL32 PixelSize;
VOL32 XLimits;
VOL32 RectangleOrigin;
VOL32 RectangleSize;
} PMRectangle;
typedef struct {
VOL32 FilterMode;
VOL32 StatisticMode;
VOL32 MinRegion;
VOL32 MaxRegion;
VOL32 ResetPickResult;
VOL32 MitHitRegion;
VOL32 MaxHitRegion;
VOL32 PickResult;
VOL32 GlintSync;
VOL32 reserved00;
VOL32 reserved01;
VOL32 reserved02;
VOL32 reserved03;
VOL32 FBBlockColorU;
VOL32 FBBlockColorL;
VOL32 SuspendUntilFrameBlank;
} PMMode;
typedef struct {
VOL32 ScissorMode;
VOL32 ScissorMinXY;
VOL32 ScissorMaxXY;
VOL32 ScreenSize;
VOL32 AreaStippleMode;
VOL32 LineStippleMode;
VOL32 LoadLineStippleCounters;
VOL32 UpdateLineStippleCounters;
VOL32 SaveLineStippleState;
VOL32 WindowOrigin;
} PMScissor;
typedef struct {
VOL32 RStart;
VOL32 dRdx;
VOL32 dRdyDom;
VOL32 GStart;
VOL32 dGdx;
VOL32 dGdyDom;
VOL32 BStart;
VOL32 dBdx;
VOL32 dBdyDom;
VOL32 AStart;
VOL32 dAdx;
VOL32 dAdyDom;
VOL32 ColorDDAMode;
VOL32 ConstantColor;
VOL32 GLINTColor;
} PMColor;
#endif
#define PM2_REG_BASE(c) ((c)->attr.address[0] & 0xFFFFC000)
#define PM2_REG_SIZE(c) (0x10000)
#define minb(p) *(volatile CARD8 *)(pm2c->reg_base + (p))
#define moutb(p,v) *(volatile CARD8 *)(pm2c->reg_base + (p)) = (v)
/* Memory mapped register access macros */
#define INREG8(addr) *(volatile CARD8 *)(pm2c->reg_base + (addr))
#define INREG16(addr) *(volatile CARD16 *)(pm2c->reg_base + (addr))
#define INREG(addr) *(volatile CARD32 *)(pm2c->reg_base + (addr))
#define OUTREG8(addr, val) do { \
*(volatile CARD8 *)(pm2c->reg_base + (addr)) = (val); \
} while (0)
#define OUTREG16(addr, val) do { \
*(volatile CARD16 *)(pm2c->reg_base + (addr)) = (val); \
} while (0)
#define OUTREG(addr, val) do { \
*(volatile CARD32 *)(pm2c->reg_base + (addr)) = (val); \
} while (0)
typedef struct _PM2CardInfo {
VesaCardPrivRec vesa;
CARD8 *reg_base;
int in_fifo_space;
int fifo_size;
int pprod;
int bppalign;
int clipping_on;
int ROP;
} PM2CardInfo;
#define getPM2CardInfo(kd) ((PM2CardInfo *) ((kd)->card->driver))
#define pmCardInfo(kd) PM2CardInfo *pm2c = getPM2CardInfo(kd)
typedef struct _PM2ScreenInfo {
VesaScreenPrivRec vesa;
CARD8 *cursor_base;
CARD8 *screen;
CARD8 *off_screen;
int off_screen_size;
KdVideoAdaptorPtr pAdaptor;
} PM2ScreenInfo;
#define getPM2ScreenInfo(kd) ((PM2ScreenInfo *) ((kd)->screen->driver))
#define pmScreenInfo(kd) PM2ScreenInfo *pm2s = getPM2ScreenInfo(kd)
Bool
pmCardInit (KdCardInfo *card);
Bool
pmScreenInit (KdScreenInfo *screen);
Bool
pmDrawInit(ScreenPtr);
void
pmDrawEnable (ScreenPtr);
void
pmDrawSync (ScreenPtr);
void
pmDrawDisable (ScreenPtr);
void
pmDrawFini (ScreenPtr);
extern KdCardFuncs PM2Funcs;
#define PM2R_MEM_CONFIG 0x10c0
#define PM2F_MEM_CONFIG_RAM_MASK (3L<<29)
#define PM2F_MEM_BANKS_1 0L
#define PM2F_MEM_BANKS_2 (1L<<29)
#define PM2F_MEM_BANKS_3 (2L<<29)
#define PM2F_MEM_BANKS_4 (3L<<29)
#endif /* _PM2_H_ */

215
hw/kdrive/pm2/pm2_draw.c Normal file
View File

@ -0,0 +1,215 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "kdrive.h"
#include "pm2.h"
static PM2CardInfo *card;
static VOL8 *mmio;
static void pmWait (PM2CardInfo *card, int n);
static void
pmWait (PM2CardInfo *card, int n)
{
if (card->in_fifo_space >= n)
card->in_fifo_space -= n;
else {
int tmp;
while((tmp = *(VOL32 *) (mmio + InFIFOSpace)) < n);
/* Clamp value due to bugs in PM3 */
if (tmp > card->fifo_size)
tmp = card->fifo_size;
card->in_fifo_space = tmp - n;
}
}
static Bool
pmPrepareSolid (PixmapPtr pPixmap,
int alu,
Pixel pm,
Pixel fg)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
KdScreenPriv(pScreen);
pmCardInfo(pScreenPriv);
card = pm2c;
if (~pm & FbFullMask(pPixmap->drawable.depth))
return FALSE;
pmWait(card, 6);
*(VOL32 *) (mmio + FBHardwareWriteMask) = pm;
if (alu == GXcopy) {
*(VOL32 *) (mmio + ColorDDAMode) = UNIT_DISABLE;
*(VOL32 *) (mmio + FBReadMode) = card->pprod;
*(VOL32 *) (mmio + FBBlockColor) = fg;
} else {
*(VOL32 *) (mmio + ColorDDAMode) = UNIT_ENABLE;
*(VOL32 *) (mmio + ConstantColor) = fg;
*(VOL32 *) (mmio + FBReadMode) = card->pprod|FBRM_DstEnable|FBRM_Packed;
}
*(VOL32 *) (mmio + LogicalOpMode) = alu<<1|UNIT_ENABLE;
card->ROP = alu;
return TRUE;
}
static void
pmSolid (int x1, int y1, int x2, int y2)
{
int speed = 0;
if (card->ROP == GXcopy) {
pmWait(card, 3);
*(VOL32 *) (mmio + RectangleOrigin) = GLINT_XY(x1, y1);
*(VOL32 *) (mmio + RectangleSize) = GLINT_XY(x2-x1, y2-y1);
speed = FastFillEnable;
} else {
pmWait(card, 4);
*(VOL32 *) (mmio + RectangleOrigin) = GLINT_XY(x1, y1);
*(VOL32 *) (mmio + RectangleSize) = GLINT_XY((x2-x1)+7, y2-y1);
*(VOL32 *) (mmio + PackedDataLimits) = x1<<16|(x1+(x2-x1));
speed = 0;
}
*(VOL32 *) (mmio + Render) = PrimitiveRectangle | XPositive | YPositive | speed;
}
static void
pmDoneSolid (void)
{
}
static Bool
pmPrepareCopy (PixmapPtr pSrcPixmap,
PixmapPtr pDstPixmap,
int dx,
int dy,
int alu,
Pixel pm)
{
ScreenPtr pScreen = pDstPixmap->drawable.pScreen;
KdScreenPriv(pScreen);
pmCardInfo(pScreenPriv);
ErrorF ("pmPrepareCopy\n");
card = pm2c;
if (~pm & FbFullMask(pDstPixmap->drawable.depth))
return FALSE;
pmWait(card, 5);
*(VOL32 *) (mmio + FBHardwareWriteMask) = pm;
*(VOL32 *) (mmio + ColorDDAMode) = UNIT_DISABLE;
if ((alu == GXset) || (alu == GXclear)) {
*(VOL32 *) (mmio + FBReadMode) = card->pprod;
} else {
if ((alu == GXcopy) || (alu == GXcopyInverted)) {
*(VOL32 *) (mmio + FBReadMode) = card->pprod|FBRM_SrcEnable;
} else {
*(VOL32 *) (mmio + FBReadMode) = card->pprod|FBRM_SrcEnable|FBRM_DstEnable;
}
}
*(VOL32 *) (mmio + LogicalOpMode) = alu<<1|UNIT_ENABLE;
card->ROP = alu;
return TRUE;
}
static void
pmCopy (int srcX,
int srcY,
int dstX,
int dstY,
int w,
int h)
{
ErrorF ("pmCopy %d %d %d %d %d %d\n", srcX, srcY, dstX, dstY, w, h);
pmWait(card, 4);
*(VOL32 *) (mmio + RectangleOrigin) = GLINT_XY(dstX, dstY);
*(VOL32 *) (mmio + RectangleSize) = GLINT_XY(w, h);
*(VOL32 *) (mmio + FBSourceDelta) = ((srcY-dstY)&0x0FFF)<<16 | (srcX-dstX)&0x0FFF;
*(VOL32 *) (mmio + Render) = PrimitiveRectangle | XPositive | YPositive;
}
static void
pmDoneCopy (void)
{
}
KaaScreenInfoRec pmKaa = {
pmPrepareSolid,
pmSolid,
pmDoneSolid,
pmPrepareCopy,
pmCopy,
pmDoneCopy,
};
Bool
pmDrawInit (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
pmCardInfo(pScreenPriv);
Bool ret = TRUE;
card = pm2c;
mmio = pm2c->reg_base;
if (pScreenPriv->screen->fb[0].depth <= 16) {
ErrorF ("depth(%d) <= 16 \n", pScreenPriv->screen->fb[0].depth);
ret = FALSE;
}
if (ret && !kaaDrawInit (pScreen, &pmKaa))
{
ErrorF ("kaaDrawInit failed\n");
ret = FALSE;
}
return ret;
}
void
pmDrawEnable (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
pmCardInfo(pScreenPriv);
pm2c->in_fifo_space = 0;
KdMarkSync (pScreen);
}
void
pmDrawDisable (ScreenPtr pScreen)
{
}
void
pmDrawFini (ScreenPtr pScreen)
{
}
void
pmDrawSync (ScreenPtr pScreen)
{
if (card->clipping_on) {
card->clipping_on = FALSE;
pmWait(card, 1);
*(VOL32 *) (mmio + ScissorMode) = 0;
}
while (*(VOL32 *) (mmio + DMACount) != 0);
pmWait(card, 2);
*(VOL32 *) (mmio + FilterMode) = 0x400;
*(VOL32 *) (mmio + GlintSync) = 0;
do {
while(*(VOL32 *) (mmio + OutFIFOWords) == 0);
} while (*(VOL32 *) (mmio + OutputFIFO) != Sync_tag);
}

54
hw/kdrive/pm2/pm2stub.c Normal file
View File

@ -0,0 +1,54 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "kdrive.h"
#include "pm2.h"
static const int PM2Cards[]={ PCI_CHIP_3DLABS_PERMEDIA2, PCI_CHIP_3DLABS_PERMEDIA2V };
#define numPM2Cards (sizeof(PM2Cards) / sizeof(PM2Cards[0]))
void
InitCard (char *name)
{
KdCardAttr attr;
int i;
Bool LinuxFindPci(CARD16, CARD16, CARD32, KdCardAttr *);
for (i = 0; i < numPM2Cards; i++)
if (LinuxFindPci (0x3d3d, PM2Cards[i], 0, &attr))
KdCardInfoAdd (&PM2Funcs, &attr, (void *) PM2Cards[i]);
}
void
InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
{
KdInitOutput (pScreenInfo, argc, argv);
}
void
InitInput (int argc, char **argv)
{
KdInitInput (&LinuxMouseFuncs, &LinuxKeyboardFuncs);
}
void
ddxUseMsg (void)
{
KdUseMsg();
vesaUseMsg();
}
int
ddxProcessArgument (int argc, char **argv, int i)
{
int ret;
if (!(ret = vesaProcessArgument (argc, argv, i)))
ret = KdProcessArgument(argc, argv, i);
return ret;
}