1
0
mirror of synced 2026-03-10 12:18:22 +00:00

preliminary EXA support for new Goblin Accel ; still some issues

This commit is contained in:
Romain Dolbeau
2022-08-15 14:59:13 +02:00
parent 6767363415
commit 15a593f44e
5 changed files with 92 additions and 140 deletions

View File

@@ -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

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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;

View File

@@ -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 */