preliminary EXA support for new Goblin Accel ; still some issues
This commit is contained in:
@@ -497,6 +497,8 @@ goblinmmap(dev_t dev, off_t off, int prot)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
device_printf(sc->sc_dev, "Jareth mmap() (from X11, presumably) failed; 0x%08llx, 0x%08x\n", off, prot);
|
||||
|
||||
return (-1);
|
||||
}
|
||||
@@ -715,6 +717,11 @@ static void
|
||||
goblin_reset(struct goblin_softc *sc)
|
||||
{
|
||||
goblin_set_depth(sc, 8);
|
||||
// X11 is supposed to clean up its mess, but just in case...
|
||||
if (sc->sc_has_jareth) {
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_jareth, GOBOFB_ACCEL_REG_SRC_PTR, 0);
|
||||
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_jareth, GOBOFB_ACCEL_REG_DST_PTR, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -38,8 +38,6 @@
|
||||
/* Various offsets in virtual (ie. mmap()) spaces Linux and Solaris support. */
|
||||
#define GOBLIN_FBC_VOFF 0x70000000
|
||||
#define JARETH_REG_VOFF 0x70001000
|
||||
#define JARETH_MICROCODE_VOFF 0x70002000
|
||||
#define JARETH_REGFILE_VOFF 0x70003000
|
||||
#define GOBLIN_RAM_VOFF 0x70016000
|
||||
|
||||
typedef struct {
|
||||
@@ -57,9 +55,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
unsigned char *fb;
|
||||
GoblinFbcPtr fbc;
|
||||
JarethRegPtr jreg;
|
||||
JarethMicrocodePtr jmicrocode;
|
||||
JarethRegfilePtr jregfile;
|
||||
GoblinAccelPtr jreg;
|
||||
int width;
|
||||
int height;
|
||||
int maxheight;
|
||||
@@ -118,18 +114,9 @@ int GOBLINEXAInit(ScreenPtr);
|
||||
#include <dev/sun/fbio.h>
|
||||
#include <sys/ioccom.h>
|
||||
#define GOBLIN_SET_PIXELMODE _IOW('M', 3, int)
|
||||
#define JARETH_FN_NUM_FILL 0
|
||||
#define JARETH_FN_NUM_FILLROP 1
|
||||
#define JARETH_FN_NUM_COPY 2
|
||||
#define JARETH_FN_NUM_COPYREV 3
|
||||
struct jareth_fn {
|
||||
int off;
|
||||
int len;
|
||||
};
|
||||
#define JARETH_FN _IOWR('j', 0, struct jareth_fn)
|
||||
#else
|
||||
#define GOBLIN_SET_PIXELMODE (('M' << 8) | 3)
|
||||
#error "toto"
|
||||
#error "Error"
|
||||
#endif
|
||||
|
||||
#endif /* GOBLIN_H */
|
||||
|
||||
@@ -38,7 +38,8 @@
|
||||
//#define DEBUG_GOBLIN 1
|
||||
|
||||
#ifdef DEBUG_GOBLIN
|
||||
#define ENTER xf86Msg(X_ERROR, "%s>\n", __func__);
|
||||
//#define ENTER xf86Msg(X_ERROR, "%s>\n", __func__);
|
||||
#define ENTER
|
||||
#define DPRINTF xf86Msg
|
||||
#else
|
||||
#define ENTER
|
||||
@@ -197,10 +198,10 @@ GOBLINEXAInit(ScreenPtr pScreen)
|
||||
pExa->offScreenBase = pGoblin->width * pGoblin->height * 4; // 32-bits
|
||||
|
||||
/*
|
||||
* Jareth has 128-bits memory access
|
||||
* Jareth has arbitrary-bits memory access, but is more efficient with 64-bits aligned data
|
||||
*/
|
||||
pExa->pixmapOffsetAlign = 16;
|
||||
pExa->pixmapPitchAlign = 16;
|
||||
pExa->pixmapOffsetAlign = 8;
|
||||
pExa->pixmapPitchAlign = 8;
|
||||
|
||||
pExa->flags = EXA_OFFSCREEN_PIXMAPS;/* | EXA_MIXED_PIXMAPS; */ /* | EXA_SUPPORTS_OFFSCREEN_OVERLAPS; */
|
||||
|
||||
@@ -231,7 +232,7 @@ GOBLINEXAInit(ScreenPtr pScreen)
|
||||
static inline void
|
||||
GoblinWait(GoblinPtr pGoblin)
|
||||
{
|
||||
uint32_t status = pGoblin->jreg->status;
|
||||
uint32_t status = pGoblin->jreg->reg_status;
|
||||
int count = 0;
|
||||
int max_count = 1000;
|
||||
int del = 1;
|
||||
@@ -240,17 +241,17 @@ GoblinWait(GoblinPtr pGoblin)
|
||||
|
||||
ENTER;
|
||||
|
||||
while ((status & 1) && (count < max_count)) {
|
||||
while ((status & 1) && (count < max_count)) { // & 1 is WORK_IN_PROGRESS_BIT
|
||||
count ++;
|
||||
usleep(del * param);
|
||||
del = del < max_del ? 2*del : del;
|
||||
status = pGoblin->jreg->status;
|
||||
status = pGoblin->jreg->reg_status;
|
||||
}
|
||||
|
||||
if (status & 1) {
|
||||
xf86Msg(X_ERROR, "Jareth wait for idle timed out %08x %08x\n", status);
|
||||
if (status & 1) { // & 1 is WORK_IN_PROGRESS_BIT
|
||||
xf86Msg(X_ERROR, "Jareth wait for idle timed out %08x\n", status);
|
||||
} else {
|
||||
xf86Msg(X_INFO, "Jareth: last operation took %d cycles (eng_clk)\n", pGoblin->jreg->cyc_counter);
|
||||
//xf86Msg(X_INFO, "Jareth: last operation took %d cycles (eng_clk)\n", pGoblin->jreg->cyc_counter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,31 +332,23 @@ GoblinPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
|
||||
|
||||
ENTER;
|
||||
DPRINTF(X_ERROR, "PrepareSolid bpp: %d, alu %d, pm 0x%08x, Fg 0x%08x\n", pPixmap->drawable.bitsPerPixel, alu, planemask, fg);
|
||||
|
||||
if ((pGoblin->jreg->power & 1) != 1)
|
||||
pGoblin->jreg->power = 1;
|
||||
|
||||
GoblinWait(pGoblin);
|
||||
|
||||
pGoblin->fg = fg;
|
||||
for (i = 0 ; i < 8; i++)
|
||||
pGoblin->jregfile->reg[1][i] = fg;
|
||||
|
||||
pGoblin->jregfile->reg[5][0] = planemask;
|
||||
pGoblin->jregfile->reg[5][1] = alu;
|
||||
//goblin->jreg->reg_XXXXX = planemask;
|
||||
pGoblin->jreg->reg_fgcolor = fg;
|
||||
|
||||
pGoblin->last_mask = planemask;
|
||||
pGoblin->last_rop = alu;
|
||||
|
||||
if ((alu == 0x3) && // GCcopy
|
||||
pGoblin->jreg->reg_dst_ptr = 0;
|
||||
|
||||
if ((alu == 0x3) && // GXcopy
|
||||
(planemask == 0xFFFFFFFF)) { // full pattern
|
||||
// fill
|
||||
pGoblin->jreg->mpstart = pGoblin->fill_off;
|
||||
pGoblin->jreg->mplen = pGoblin->fill_len;
|
||||
} else {
|
||||
// fillrop
|
||||
pGoblin->jreg->mpstart = pGoblin->fillrop_off;
|
||||
pGoblin->jreg->mplen = pGoblin->fillrop_len;
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -380,28 +373,29 @@ GoblinSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
|
||||
switch (depth) {
|
||||
case 32:
|
||||
start = dstoff + (y1 * dstpitch) + (x1 << 2);
|
||||
/* we work in bytes not pixels */
|
||||
w = w * 4;
|
||||
break;
|
||||
case 8:
|
||||
start = dstoff + (y1 * dstpitch) + x1;
|
||||
break;
|
||||
}
|
||||
|
||||
ptr = 0x8f000000; // fixme
|
||||
ptr = 0x8f000000; // fixme!
|
||||
ptr += start;
|
||||
|
||||
GoblinWait(pGoblin);
|
||||
|
||||
pGoblin->jregfile->reg[0][0] = ptr;
|
||||
pGoblin->jregfile->reg[2][0] = w;
|
||||
pGoblin->jregfile->reg[3][0] = h;
|
||||
pGoblin->jregfile->reg[4][0] = dstpitch;
|
||||
pGoblin->jreg->reg_width = w;
|
||||
pGoblin->jreg->reg_height = h;
|
||||
pGoblin->jreg->reg_dst_stride = dstpitch;
|
||||
pGoblin->jreg->reg_bitblt_dst_x = x1;
|
||||
pGoblin->jreg->reg_bitblt_dst_y = y1;
|
||||
|
||||
DPRINTF(X_ERROR, "Solid %d %d %d %d [%d %d], %d %d -> %d (%p: %p)\n", x1, y1, x2, y2,
|
||||
DPRINTF(X_INFO, "Solid {%d} %d %d %d %d [%d %d], %d %d -> %d (%p: %p)\n",
|
||||
depth,
|
||||
x1, y1, x2, y2,
|
||||
w, h, dstpitch, dstoff, start, (void*)start, ptr);
|
||||
|
||||
pGoblin->jreg->control = 1; // start
|
||||
pGoblin->jreg->reg_cmd = 2; // 1<<DO_FILL_BIT
|
||||
|
||||
exaMarkSync(pPixmap->drawable.pScreen);
|
||||
}
|
||||
@@ -425,8 +419,8 @@ GoblinPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap,
|
||||
|
||||
GoblinWait(pGoblin);
|
||||
|
||||
pGoblin->jregfile->reg[5][0] = planemask;
|
||||
pGoblin->jregfile->reg[5][1] = alu;
|
||||
//goblin->jreg->reg_XXXXX = planemask;
|
||||
//goblin->jreg->reg_XXXXX = alu;
|
||||
|
||||
pGoblin->last_mask = planemask;
|
||||
pGoblin->last_rop = alu;
|
||||
@@ -435,23 +429,17 @@ GoblinPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap,
|
||||
if ((alu == 0x3) && // GCcopy
|
||||
(planemask == 0xFFFFFFFF)) { // full pattern
|
||||
// fill
|
||||
pGoblin->jreg->mpstart = pGoblin->copy_off;
|
||||
pGoblin->jreg->mplen = pGoblin->copy_len;
|
||||
} else {
|
||||
// fillrop
|
||||
pGoblin->jreg->mpstart = pGoblin->copy_off; // FIXME
|
||||
pGoblin->jreg->mplen = pGoblin->copy_len;
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
if ((alu == 0x3) && // GCcopy
|
||||
(planemask == 0xFFFFFFFF)) { // full pattern
|
||||
// fill
|
||||
pGoblin->jreg->mpstart = pGoblin->copyrev_off;
|
||||
pGoblin->jreg->mplen = pGoblin->copyrev_len;
|
||||
} else {
|
||||
// fillrop
|
||||
pGoblin->jreg->mpstart = pGoblin->copyrev_off; // FIXME
|
||||
pGoblin->jreg->mplen = pGoblin->copyrev_len;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -476,33 +464,42 @@ GoblinCopy(PixmapPtr pDstPixmap,
|
||||
srcstart = (srcX << 2) + (pGoblin->srcpitch * srcY) + pGoblin->srcoff;
|
||||
dststart = (dstX << 2) + ( dstpitch * dstY) + dstoff;
|
||||
#if 1
|
||||
src = (char*)0x8f000000 + srcstart; // fixme
|
||||
dst = (char*)0x8f000000 + dststart;
|
||||
//src = (char*)0x8f000000 + srcstart; // fixme: hw'ired @
|
||||
//dst = (char*)0x8f000000 + dststart; // fixme: hw'ired @
|
||||
|
||||
if (pGoblin->ydir < 0) {
|
||||
/*
|
||||
if (pGoblin->ydir < 0) {
|
||||
src += pGoblin->srcpitch * (h-1);
|
||||
dst += dstpitch * (h-1);
|
||||
pGoblin->srcpitch = -pGoblin->srcpitch;
|
||||
dstpitch = -dstpitch;
|
||||
}
|
||||
|
||||
// 32 bits
|
||||
w = w*4;
|
||||
*/
|
||||
|
||||
GoblinWait(pGoblin);
|
||||
|
||||
pGoblin->jregfile->reg[0][0] = (uint32_t)dst;
|
||||
pGoblin->jregfile->reg[0][1] = (uint32_t)src;
|
||||
pGoblin->jregfile->reg[1][0] = (uint32_t)src;
|
||||
pGoblin->jregfile->reg[1][1] = (uint32_t)dst;
|
||||
pGoblin->jregfile->reg[2][0] = w;
|
||||
pGoblin->jregfile->reg[3][0] = h;
|
||||
pGoblin->jregfile->reg[4][0] = dstpitch;
|
||||
pGoblin->jregfile->reg[4][1] = pGoblin->srcpitch;
|
||||
pGoblin->jreg->reg_width = w;
|
||||
pGoblin->jreg->reg_height = h;
|
||||
pGoblin->jreg->reg_src_stride = pGoblin->srcpitch;
|
||||
pGoblin->jreg->reg_dst_stride = dstpitch;
|
||||
pGoblin->jreg->reg_bitblt_src_x = srcX;
|
||||
pGoblin->jreg->reg_bitblt_src_y = srcY;
|
||||
pGoblin->jreg->reg_bitblt_dst_x = dstX;
|
||||
pGoblin->jreg->reg_bitblt_dst_y = dstY;
|
||||
|
||||
DPRINTF(X_ERROR, "Copy %d %d -> %d %d [%d x %d, %d %d] ; %d -> %d \n", srcX, srcY, dstX, dstY, w, h, pGoblin->xdir, pGoblin->ydir, srcstart, dststart);
|
||||
if (pGoblin->srcoff != 0)
|
||||
pGoblin->jreg->reg_src_ptr = (0x8f000000 + pGoblin->srcoff); // fixme: hw'ired @
|
||||
else
|
||||
pGoblin->jreg->reg_src_ptr = 0;
|
||||
if (dstoff != 0)
|
||||
pGoblin->jreg->reg_dst_ptr = (0x8f000000 + dstoff); // fixme: hw'ired @
|
||||
else
|
||||
pGoblin->jreg->reg_dst_ptr = 0;
|
||||
|
||||
pGoblin->jreg->control = 1; // start
|
||||
//DPRINTF(X_ERROR, "Copy %d %d -> %d %d [%d x %d, %d %d] ; %d -> %d \n", srcX, srcY, dstX, dstY, w, h, pGoblin->xdir, pGoblin->ydir, srcstart, dststart);
|
||||
DPRINTF(X_ERROR, "Copy %d %d -> %d %d [%d x %d, %d %d] ; 0x%08x 0x%08x ; %d %d \n", srcX, srcY, dstX, dstY, w, h, pGoblin->xdir, pGoblin->ydir, pGoblin->srcoff, dstoff, pGoblin->srcpitch, dstpitch);
|
||||
|
||||
pGoblin->jreg->reg_cmd = 1; // 1<<DO_COPY_BIT
|
||||
|
||||
exaMarkSync(pDstPixmap->drawable.pScreen);
|
||||
|
||||
|
||||
@@ -545,53 +545,12 @@ GOBLINScreenInit(SCREEN_INIT_ARGS_DECL)
|
||||
|
||||
if (pGoblin->has_accel && !pGoblin->NoAccel) {
|
||||
// map Jareth registers
|
||||
pGoblin->jreg = xf86MapSbusMem(psdp, JARETH_REG_VOFF, sizeof(JarethReg));
|
||||
pGoblin->jmicrocode = xf86MapSbusMem(psdp, JARETH_MICROCODE_VOFF, sizeof(JarethReg));
|
||||
pGoblin->jregfile = xf86MapSbusMem(psdp, JARETH_REGFILE_VOFF, sizeof(JarethMicrocode));
|
||||
if ((pGoblin->jreg == NULL) ||
|
||||
(pGoblin->jmicrocode == NULL) ||
|
||||
(pGoblin->jregfile == NULL)) {
|
||||
pGoblin->jreg = xf86MapSbusMem(psdp, JARETH_REG_VOFF, sizeof(GoblinAccel));
|
||||
if (pGoblin->jreg == NULL) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86MapSbusMem failed for Jareth\n");
|
||||
pGoblin->has_accel = FALSE;
|
||||
} else {
|
||||
struct jareth_fn jfn;
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Jareth successfully mapped\n");
|
||||
// get some functions
|
||||
jfn.off = JARETH_FN_NUM_FILL;
|
||||
if (ioctl (pGoblin->psdp->fd, JARETH_FN, &jfn) || (jfn.off == -1)) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Fill function retrieval failed for Jareth\n");
|
||||
pGoblin->has_accel = FALSE;
|
||||
} else {
|
||||
pGoblin->fill_off = jfn.off;
|
||||
pGoblin->fill_len = jfn.len;
|
||||
}
|
||||
jfn.off = JARETH_FN_NUM_FILLROP;
|
||||
if (ioctl (pGoblin->psdp->fd, JARETH_FN, &jfn) || (jfn.off == -1)) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Fillrop function retrieval failed for Jareth\n");
|
||||
pGoblin->has_accel = FALSE;
|
||||
} else {
|
||||
pGoblin->fillrop_off = jfn.off;
|
||||
pGoblin->fillrop_len = jfn.len;
|
||||
}
|
||||
jfn.off = JARETH_FN_NUM_COPY;
|
||||
if (ioctl (pGoblin->psdp->fd, JARETH_FN, &jfn) || (jfn.off == -1)) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Copy function retrieval failed for Jareth\n");
|
||||
pGoblin->has_accel = FALSE;
|
||||
} else {
|
||||
pGoblin->copy_off = jfn.off;
|
||||
pGoblin->copy_len = jfn.len;
|
||||
}
|
||||
jfn.off = JARETH_FN_NUM_COPYREV;
|
||||
if (ioctl (pGoblin->psdp->fd, JARETH_FN, &jfn) || (jfn.off == -1)) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Copyrev function retrieval failed for Jareth\n");
|
||||
pGoblin->has_accel = FALSE;
|
||||
} else {
|
||||
pGoblin->copyrev_off = jfn.off;
|
||||
pGoblin->copyrev_len = jfn.len;
|
||||
}
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Jareth functions: fill %d %d, fillrop %d %d, copy %d %d, copyrev %d %d\n",
|
||||
pGoblin->fill_off, pGoblin->fill_len, pGoblin->fillrop_off, pGoblin->fillrop_len,
|
||||
pGoblin->copy_off, pGoblin->copy_len, pGoblin->copyrev_off, pGoblin->copyrev_len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -789,6 +748,13 @@ GOBLINCloseScreen(CLOSE_SCREEN_ARGS_DECL)
|
||||
|
||||
pScrn->vtSema = FALSE;
|
||||
|
||||
if (pGoblin->jreg) {
|
||||
pGoblin->jreg->reg_src_ptr = 0;
|
||||
pGoblin->jreg->reg_dst_ptr = 0;
|
||||
xf86UnmapSbusMem(psdp, pGoblin->jreg, sizeof(GoblinAccel));
|
||||
pGoblin->jreg = NULL;
|
||||
}
|
||||
|
||||
if (pGoblin->fbc) {
|
||||
xf86UnmapSbusMem(psdp, pGoblin->fbc, sizeof(*pGoblin->fbc));
|
||||
pGoblin->fbc = NULL;
|
||||
|
||||
@@ -66,28 +66,23 @@ typedef struct goblin_fbc {
|
||||
volatile uint32_t curbits[32]; /* 0x40 .. 0x5f */
|
||||
} GoblinFbc, *GoblinFbcPtr;
|
||||
|
||||
typedef struct jareth_reg {
|
||||
volatile uint32_t window;
|
||||
volatile uint32_t mpstart;
|
||||
volatile uint32_t mplen;
|
||||
volatile uint32_t control;
|
||||
volatile uint32_t mpresume;
|
||||
volatile uint32_t power;
|
||||
volatile uint32_t status;
|
||||
volatile uint32_t ev_status;
|
||||
volatile uint32_t ev_prending;
|
||||
volatile uint32_t ev_enable;
|
||||
volatile uint32_t instruction;
|
||||
volatile uint32_t ls_status;
|
||||
volatile uint32_t cyc_counter;
|
||||
} JarethReg, *JarethRegPtr;
|
||||
|
||||
typedef struct jareth_microcode {
|
||||
volatile uint32_t mc[1024];
|
||||
} JarethMicrocode, *JarethMicrocodePtr;
|
||||
|
||||
typedef struct jareth_regfile {
|
||||
volatile uint32_t reg[32][8];
|
||||
} JarethRegfile, *JarethRegfilePtr;
|
||||
typedef struct goblin_accel_regs {
|
||||
u_int32_t reg_status; // 0
|
||||
u_int32_t reg_cmd;
|
||||
u_int32_t reg_r5_cmd;
|
||||
u_int32_t resv0;
|
||||
u_int32_t reg_width; // 4
|
||||
u_int32_t reg_height;
|
||||
u_int32_t reg_fgcolor;
|
||||
u_int32_t resv2;
|
||||
u_int32_t reg_bitblt_src_x; // 8
|
||||
u_int32_t reg_bitblt_src_y;
|
||||
u_int32_t reg_bitblt_dst_x;
|
||||
u_int32_t reg_bitblt_dst_y;
|
||||
u_int32_t reg_src_stride; // 12
|
||||
u_int32_t reg_dst_stride;
|
||||
u_int32_t reg_src_ptr; // 14
|
||||
u_int32_t reg_dst_ptr;
|
||||
} GoblinAccel, *GoblinAccelPtr;
|
||||
|
||||
#endif /* GOBLIN_REGS_H */
|
||||
|
||||
Reference in New Issue
Block a user