1
0
mirror of synced 2026-04-24 19:50:12 +00:00

first go at jareth-with-goblin

This commit is contained in:
Romain Dolbeau
2022-03-11 23:02:43 +01:00
parent 9ee9bcd692
commit a87e7eaa6b
11 changed files with 741 additions and 147 deletions

View File

@@ -71,13 +71,16 @@ static void goblinloadcmap(struct goblin_softc *, int, int);
static void goblin_set_video(struct goblin_softc *, int);
static int goblin_get_video(struct goblin_softc *);
static void jareth_copyrows(void *, int, int, int);
dev_type_open(goblinopen);
dev_type_close(goblinclose);
dev_type_ioctl(goblinioctl);
dev_type_mmap(goblinmmap);
const struct cdevsw goblin_cdevsw = {
.d_open = goblinopen,
.d_close = nullclose,
.d_close = goblinclose,
.d_read = noread,
.d_write = nowrite,
.d_ioctl = goblinioctl,
@@ -107,12 +110,39 @@ struct wsscreen_descr goblin_defaultscreen = {
NULL /* modecookie */
};
struct scrolltest {
int y0;
int y1;
int x0;
int w;
int n;
};
#define GOBLIN_SCROLL _IOW('X', 0, struct scrolltest)
#define GOBLIN_FILL _IOW('X', 1, struct scrolltest)
static int goblin_ioctl(void *, void *, u_long, void *, int, struct lwp *);
static paddr_t goblin_mmap(void *, void *, off_t, int);
static void goblin_init_screen(void *, struct vcons_screen *, int, long *);
int goblin_putcmap(struct goblin_softc *, struct wsdisplay_cmap *);
int goblin_getcmap(struct goblin_softc *, struct wsdisplay_cmap *);
static int goblin_putcmap(struct goblin_softc *, struct wsdisplay_cmap *);
static int goblin_getcmap(struct goblin_softc *, struct wsdisplay_cmap *);
static void goblin_init(struct goblin_softc *);
static void goblin_reset(struct goblin_softc *);
/* Jareth stuff */
static int init_programs(struct goblin_softc *sc);
static int power_on(struct goblin_softc *sc);
static int power_off(struct goblin_softc *sc);
static int scroll(struct goblin_softc *sc, int y0, int y1, int x0, int w, int n);
static int fill(struct goblin_softc *sc, int y0, int pat, int x0, int w, int n);
static const uint32_t program_scroll128[12] = { 0x407c0012,0x00140080,0x201c0013,0x60fc7013,0x00170146,0xfe000148,0x000e10c6,0x010000c9,0x00004005,0xfb000809,0x0000000a,0x0000000a };
static const uint32_t program_fill128[12] = { 0x407c0012,0x00140080,0x607c1013,0x00170146,0xfe800148,0x000e10c6,0x010000c9,0x00004005,0xfb800809,0x0000000a,0x0000000a,0x0000000a };
static const uint32_t* programs[3] = { program_scroll128, program_fill128, NULL };
static const uint32_t program_len[3] = { 12, 12, 0 };
static uint32_t program_offset[3];
static void goblin_set_depth(struct goblin_softc *, int);
struct wsdisplay_accessops goblin_accessops = {
goblin_ioctl,
@@ -148,9 +178,23 @@ goblinattach(struct goblin_softc *sc, const char *name, int isconsole)
unsigned long defattr;
volatile struct goblin_fbcontrol *fbc = sc->sc_fbc;
/* boot Jareth if present */
if (sc->sc_has_jareth) {
/* first we need to turn the engine power on ... */
power_on(sc);
if (init_programs(sc)) {
if (init_programs(sc)) {
aprint_normal_dev(sc->sc_dev, "INIT - FAILED\n");
sc->sc_has_jareth = 0;
}
}
power_off(sc);
}
fb->fb_driver = &goblinfbdriver;
fb->fb_pfour = NULL;
fb->fb_type.fb_cmsize = 256;
fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes;
fb->fb_type.fb_size = sc->sc_size; //fb->fb_type.fb_height * fb->fb_linebytes;
printf(": %s, %d x %d", name,
fb->fb_type.fb_width, fb->fb_type.fb_height);
@@ -158,7 +202,6 @@ goblinattach(struct goblin_softc *sc, const char *name, int isconsole)
fbc->vbl_mask = GOBOFB_VBL_MASK_OFF;
/* Enable display in a supported mode */
fbc->videoctrl = GOBOFB_VIDEOCTRL_OFF;
fbc->mode = GOBOFB_MODE_8BIT;
fbc->videoctrl = GOBOFB_VIDEOCTRL_ON;
@@ -173,25 +216,31 @@ goblinattach(struct goblin_softc *sc, const char *name, int isconsole)
sc->sc_stride = fb->fb_type.fb_width;
sc->sc_height = fb->fb_type.fb_height;
wsfont_init();
/* setup rasops and so on for wsdisplay */
sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
sc->sc_opens = 0;
vcons_init(&sc->vd, sc, &goblin_defaultscreen, &goblin_accessops);
sc->vd.init_screen = goblin_init_screen;
vcons_init(&sc->sc_vd, sc, &goblin_defaultscreen, &goblin_accessops);
sc->sc_vd.init_screen = goblin_init_screen;
if(isconsole) {
/* we mess with gobo_console_screen only once */
vcons_init_screen(&sc->vd, &gobo_console_screen, 1,
&defattr);
goblin_set_depth(sc, 8);
vcons_init_screen(&sc->sc_vd, &gobo_console_screen, 1,
&defattr);
/* clear the screen */
memset(sc->sc_fb.fb_pixels, (defattr >> 16) & 0xff,
sc->sc_stride * sc->sc_height);
sc->sc_stride * sc->sc_height);
gobo_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
goblin_defaultscreen.textops = &ri->ri_ops;
goblin_defaultscreen.capabilities = ri->ri_caps;
goblin_defaultscreen.nrows = ri->ri_rows;
goblin_defaultscreen.ncols = ri->ri_cols;
sc->vd.active = &gobo_console_screen;
sc->sc_vd.active = &gobo_console_screen;
wsdisplay_cnattach(&goblin_defaultscreen, ri, 0, 0, defattr);
vcons_replay_msgbuf(&gobo_console_screen);
} else {
@@ -199,15 +248,17 @@ goblinattach(struct goblin_softc *sc, const char *name, int isconsole)
* we're not the console so we just clear the screen and don't
* set up any sort of text display
*/
memset(sc->sc_fb.fb_pixels, (defattr >> 16) & 0xff,
sc->sc_stride * sc->sc_height);
}
/* Initialize the default color map. */
gobo_setup_palette(sc);
aa.scrdata = &goblin_screenlist;
aa.console = isconsole;
aa.accessops = &goblin_accessops;
aa.accesscookie = &sc->vd;
aa.accesscookie = &sc->sc_vd;
config_found(sc->sc_dev, &aa, wsemuldisplaydevprint);
}
@@ -215,10 +266,38 @@ goblinattach(struct goblin_softc *sc, const char *name, int isconsole)
int
goblinopen(dev_t dev, int flags, int mode, struct lwp *l)
{
int unit = minor(dev);
if (device_lookup(&goblin_cd, unit) == NULL)
struct goblin_softc *sc = device_lookup_private(&goblin_cd,
minor(dev));
int oldopens;
if (sc == NULL)
return (ENXIO);
oldopens = sc->sc_opens++;
if (oldopens == 0) /* first open only */
goblin_init(sc);
return (0);
}
int
goblinclose(dev_t dev, int flags, int mode, struct lwp *l)
{
struct goblin_softc *sc = device_lookup_private(&goblin_cd,
minor(dev));
int opens;
opens = --sc->sc_opens;
if (sc->sc_opens < 0) /* should not happen... */
opens = sc->sc_opens = 0;
/*
* Restore video state to make the PROM happy, on last close.
*/
if (opens == 0) {
goblin_reset(sc);
}
return (0);
}
@@ -270,6 +349,28 @@ goblinioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l)
goblin_set_video(sc, *(int *)data);
break;
case GOBLIN_SET_PIXELMODE: {
int depth = *(int *)data;
if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)
return EINVAL;
goblin_set_depth(sc, depth);
}
break;
case GOBLIN_SCROLL: {
struct scrolltest *st = (struct scrolltest *)data;
scroll(sc, st->y0, st->y1, st->x0, st->w, st->n);
}
break;
case GOBLIN_FILL: {
struct scrolltest *st = (struct scrolltest *)data;
fill(sc, st->y0, st->y1, st->x0, st->w, st->n);
}
break;
default:
return (ENOTTY);
}
@@ -284,6 +385,13 @@ goblinunblank(device_t self)
{
struct goblin_softc *sc = device_private(self);
#if NWSDISPLAY > 0
if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) {
goblin_set_depth(sc, 8);
vcons_redraw_screen(sc->sc_vd.active);
sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
}
#endif
goblin_set_video(sc, 1);
}
@@ -425,7 +533,7 @@ goblin_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
struct vcons_data *vd = v;
struct goblin_softc *sc = vd->cookie;
struct wsdisplay_fbinfo *wdf;
struct vcons_screen *ms = sc->vd.active;
struct vcons_screen *ms = sc->sc_vd.active;
struct rasops_info *ri = &ms->scr_ri;
switch (cmd) {
case WSDISPLAYIO_GTYPE:
@@ -486,7 +594,7 @@ goblin_mmap(void *v, void *vs, off_t offset, int prot)
prot, BUS_SPACE_MAP_LINEAR);
}
int
static int
goblin_putcmap(struct goblin_softc *sc, struct wsdisplay_cmap *cm)
{
u_int index = cm->index;
@@ -516,7 +624,7 @@ goblin_putcmap(struct goblin_softc *sc, struct wsdisplay_cmap *cm)
return 0;
}
int
static int
goblin_getcmap(struct goblin_softc *sc, struct wsdisplay_cmap *cm)
{
u_int index = cm->index;
@@ -552,7 +660,7 @@ goblin_init_screen(void *cookie, struct vcons_screen *scr,
struct goblin_softc *sc = cookie;
struct rasops_info *ri = &scr->scr_ri;
scr->scr_flags |= VCONS_DONT_READ;
scr->scr_flags |= VCONS_NO_COPYCOLS;
ri->ri_depth = 8;
ri->ri_width = sc->sc_width;
@@ -568,4 +676,310 @@ goblin_init_screen(void *cookie, struct vcons_screen *scr,
sc->sc_width / ri->ri_font->fontwidth);
ri->ri_hw = scr;
if (sc->sc_has_jareth) {
ri->ri_ops.copyrows = jareth_copyrows;
device_printf(sc->sc_dev, "Jareth enabled\n");
}
}
static void
goblin_set_depth(struct goblin_softc *sc, int depth)
{
if (sc->sc_depth == depth)
return;
switch (depth) {
case 8:
sc->sc_fbc->mode = GOBOFB_MODE_8BIT;
sc->sc_depth = 8;
break;
case 32:
sc->sc_fbc->mode = GOBOFB_MODE_24BIT;
sc->sc_depth = 32;
break;
default:
printf("%s: can't change to depth %d\n",
device_xname(sc->sc_dev), depth);
}
}
/* Initialize the framebuffer, storing away useful state for later reset */
static void
goblin_init(struct goblin_softc *sc)
{
//goblin_set_depth(sc, 32);
}
static void
/* Restore the state saved on goblin_init */
goblin_reset(struct goblin_softc *sc)
{
//goblin_set_depth(sc, 8);
}
#define CONFIG_CSR_DATA_WIDTH 32
#define sbusfpga_jareth_softc goblin_softc
#include "dev/sbus/sbusfpga_csr_jareth.h"
#undef sbusfpga_jareth_softc
#define REG_BASE(reg) (base + (reg * 32))
#define SUBREG_ADDR(reg, off) (REG_BASE(reg) + (off)*4)
static int start_job(struct goblin_softc *sc);
static int wait_job(struct goblin_softc *sc, uint32_t param);
static int scroll(struct goblin_softc *sc, int y0, int y1, int x0, int w, int n) {
const uint32_t base = 0;
const int pidx = 0;
int i;
power_on(sc);
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(0,0), (0x8f800000 + y0 * sc->sc_stride + x0));
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(0,1), (0x8f800000 + y1 * sc->sc_stride + x0));
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(2,0), (w));
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(3,0), (n));
for (i = 1 ; i < 8 ; i++) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(2,i), 0);
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(3,i), 0);
}
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(4,0), (sc->sc_stride));
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(4,1), (sc->sc_stride));
jareth_mpstart_write(sc, program_offset[pidx]);
jareth_mplen_write(sc, program_len[pidx]);
(void)start_job(sc);
delay(1);
(void)wait_job(sc, 2);
power_off(sc);
return 0;
}
static int fill(struct goblin_softc *sc, int y0, int pat, int x0, int w, int n) {
const uint32_t base = 0;
const int pidx = 1;
int i;
power_on(sc);
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(0,0), (0x8f800000 + y0 * sc->sc_stride + x0));
for (i = 0 ; i < 8 ; i++) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(1,i), pat);
}
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(2,0), (w));
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(3,0), (n));
for (i = 1 ; i < 8 ; i++) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(2,i), 0);
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(3,i), 0);
}
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(4,0), (sc->sc_stride));
jareth_mpstart_write(sc, program_offset[pidx]);
jareth_mplen_write(sc, program_len[pidx]);
(void)start_job(sc);
delay(1);
(void)wait_job(sc, 1);
power_off(sc);
return 0;
}
static void
jareth_copyrows(void *cookie, int src, int dst, int n)
{
struct rasops_info *ri = cookie;
struct vcons_screen *scr = ri->ri_hw;
struct goblin_softc *sc = scr->scr_cookie;
if (dst == src)
return;
if (src < 0) {
n += src;
src = 0;
}
if (src+n > ri->ri_rows)
n = ri->ri_rows - src;
if (dst < 0) {
n += dst;
dst = 0;
}
if (dst+n > ri->ri_rows)
n = ri->ri_rows - dst;
if (n <= 0)
return;
n *= ri->ri_font->fontheight;
src *= ri->ri_font->fontheight;
dst *= ri->ri_font->fontheight;
int x0 = ri->ri_xorigin;
int y0 = ri->ri_yorigin + src;
//int x1 = ri->ri_xorigin + ri->ri_emuwidth - 1;
/* int y1 = ri->ri_yorigin + src + n - 1; */
/* int x2 = ri->ri_xorigin; */
int y2 = ri->ri_yorigin + dst;
/* int x3 = ri->ri_xorigin + ri->ri_emuwidth - 1; */
/* int y3 = ri->ri_yorigin + dst + n - 1; */
scroll(sc, y0, y2, x0, ri->ri_emuwidth, n);
#if 0
if (y0 > y2) {
int x, y;
for (y = 0 ; y < n ; y++) {
for (x = x0 & ~3 ; x < x1 ; x+= 4) {
uint32_t* srcadr = (uint32_t*)(((uint8_t*)sc->sc_fb.fb_pixels) + (y0 + y) * sc->sc_stride + x);
uint32_t* dstadr = (uint32_t*)(((uint8_t*)sc->sc_fb.fb_pixels) + (y2 + y) * sc->sc_stride + x);
*dstadr = *srcadr;
}
}
} else {
int x, y;
for (y = n-1 ; y >= 0 ; y--) {
for (x = x0 & ~3; x < x1 ; x+= 4) {
uint32_t* srcadr = (uint32_t*)(((uint8_t*)sc->sc_fb.fb_pixels) + (y0 + y) * sc->sc_stride + x);
uint32_t* dstadr = (uint32_t*)(((uint8_t*)sc->sc_fb.fb_pixels) + (y2 + y) * sc->sc_stride + x);
*dstadr = *srcadr;
}
}
}
#endif
}
static int start_job(struct goblin_softc *sc) {
uint32_t status = jareth_status_read(sc);
if (status & (1<<CSR_JARETH_STATUS_RUNNING_OFFSET)) {
aprint_error_dev(sc->sc_dev, "START - Jareth status: 0x%08x, still running?\n", status);
return ENXIO;
}
jareth_control_write(sc, 1);
//aprint_normal_dev(sc->sc_dev, "START - Jareth status: 0x%08x\n", jareth_status_read(sc));
return 0;
}
static int wait_job(struct goblin_softc *sc, uint32_t param) {
uint32_t status = jareth_status_read(sc);
int count = 0;
int max_count = 2000;
int del = 1;
const int max_del = 64;
static int max_del_seen = 1;
static int max_cnt_seen = 0;
while ((status & (1<<CSR_JARETH_STATUS_RUNNING_OFFSET)) && (count < max_count)) {
//uint32_t ls_status = jareth_ls_status_read(sc);
//aprint_normal_dev(sc->sc_dev, "WAIT - ongoing, Jareth status: 0x%08x [%d] ls_status: 0x%08x\n", status, count, ls_status);
count ++;
delay(del * param);
del = del < max_del ? 2*del : del;
status = jareth_status_read(sc);
}
if (del > max_del_seen) {
max_del_seen = del;
aprint_normal_dev(sc->sc_dev, "WAIT - new max delay %d after %d count (param was %u)\n", max_del_seen, count, param);
}
if (count > max_cnt_seen) {
max_cnt_seen = count;
aprint_normal_dev(sc->sc_dev, "WAIT - new max count %d with %d delay (param was %u)\n", max_cnt_seen, del, param);
}
//jareth_control_write(sc, 0);
if (status & (1<<CSR_JARETH_STATUS_RUNNING_OFFSET)) {
aprint_error_dev(sc->sc_dev, "WAIT - Jareth status: 0x%08x (pc 0x%08x), did not finish in time? [inst: 0x%08x ls_status: 0x%08x]\n", status, (status>>1)&0x03ff, jareth_instruction_read(sc), jareth_ls_status_read(sc));
return ENXIO;
} else if (status & (1<<CSR_JARETH_STATUS_SIGILL_OFFSET)) {
aprint_error_dev(sc->sc_dev, "WAIT - Jareth status: 0x%08x, sigill [inst: 0x%08x ls_status: 0x%08x]\n", status, jareth_instruction_read(sc), jareth_ls_status_read(sc));
return ENXIO;
} else if (status & (1<<CSR_JARETH_STATUS_ABORT_OFFSET)) {
aprint_error_dev(sc->sc_dev, "WAIT - Jareth status: 0x%08x, aborted [inst: 0x%08x ls_status: 0x%08x]\n", status, jareth_instruction_read(sc), jareth_ls_status_read(sc));
return ENXIO;
} else {
//aprint_normal_dev(sc->sc_dev, "WAIT - Jareth status: 0x%08x [%d] ls_status: 0x%08x\n", status, count, jareth_ls_status_read(sc));
}
return 0;
}
static int init_programs(struct goblin_softc *sc) {
/* the microcode is a the beginning */
int err = 0;
uint32_t i, j;
uint32_t offset = 0;
for (j = 0 ; programs[j] != NULL; j ++) {
program_offset[j] = offset;
for (i = 0 ; i < program_len[j] ; i++) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_microcode, ((offset+i)*4), programs[j][i]);
if ((i%16)==15)
delay(1);
}
offset += program_len[j];
}
jareth_window_write(sc, 0); /* could use window_window to access fields, but it creates a RMW cycle for nothing */
jareth_mpstart_write(sc, 0); /* EC25519 */
jareth_mplen_write(sc, program_len[0]); /* EC25519 */
aprint_normal_dev(sc->sc_dev, "INIT - Jareth status: 0x%08x\n", jareth_status_read(sc));
#if 1
/* double check */
u_int32_t x;
int count = 0;
for (i = 0 ; i < program_len[0] && count < 10; i++) {
x = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_microcode, (i*4));
if (x != programs[0][i]) {
aprint_error_dev(sc->sc_dev, "INIT - Jareth program failure: [%d] 0x%08x <> 0x%08x\n", i, x, programs[0][i]);
err = 1;
count ++;
}
if ((i%8)==7)
delay(1);
}
if ((x = jareth_window_read(sc)) != 0) {
aprint_error_dev(sc->sc_dev, "INIT - Jareth register failure: window = 0x%08x\n", x);
err = 1;
}
if ((x = jareth_mpstart_read(sc)) != 0) {
aprint_error_dev(sc->sc_dev, "INIT - Jareth register failure: mpstart = 0x%08x\n", x);
err = 1;
}
if ((x = jareth_mplen_read(sc)) != program_len[0]) {
aprint_error_dev(sc->sc_dev, "INIT - Jareth register failure: mplen = 0x%08x\n", x);
err = 1;
}
const int test_reg_num = 73;
const uint32_t test_reg_value = 0x0C0FFEE0;
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile, 4*test_reg_num, test_reg_value);
delay(1);
if ((x = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile, 4*test_reg_num)) != test_reg_value) {
aprint_error_dev(sc->sc_dev, "INIT - Jareth register file failure: 0x%08x != 0x%08x\n", x, test_reg_value);
err = 1;
}
#endif
return err;
}
static int power_on(struct goblin_softc *sc) {
int err = 0;
if ((jareth_power_read(sc) & 1) == 0) {
jareth_power_write(sc, 1);
delay(1);
}
return err;
}
static int power_off(struct goblin_softc *sc) {
int err = 0;
jareth_power_write(sc, 0);
return err;
}

View File

@@ -155,5 +155,53 @@ goblinattach_sbus(device_t parent, device_t self, void *args)
fb->fb_pixels = (char *)bus_space_vaddr(sa->sa_bustag, bh);
}
sc->sc_has_jareth = prom_getpropint(node, "goblin_has_jareth", 0);
if (sc->sc_has_jareth) {
if (sa->sa_nreg < 5) {
aprint_error(": Not enough registers spaces for Jareth\n");
sc->sc_has_jareth = 0;
} else {
/* map registers */
if (sbus_bus_map(sc->sc_bustag,
sa->sa_reg[2].oa_space /* sa_slot */,
sa->sa_reg[2].oa_base /* sa_offset */,
sa->sa_reg[2].oa_size /* sa_size */,
BUS_SPACE_MAP_LINEAR,
&sc->sc_bhregs_jareth) != 0) {
aprint_error(": cannot map Jareth registers\n");
sc->sc_has_jareth = 0;
} else {
aprint_normal_dev(self, "Jareth registers @ %p\n", (void*)sc->sc_bhregs_jareth);
/* map microcode */
if (sbus_bus_map(sc->sc_bustag,
sa->sa_reg[3].oa_space /* sa_slot */,
sa->sa_reg[3].oa_base /* sa_offset */,
sa->sa_reg[3].oa_size /* sa_size */,
BUS_SPACE_MAP_LINEAR,
&sc->sc_bhregs_microcode) != 0) {
aprint_error(": cannot map Jareth microcode\n");
sc->sc_has_jareth = 0;
} else {
aprint_normal_dev(self, "Jareth microcode @ %p\n", (void*)sc->sc_bhregs_microcode);
/* map register file */
if (sbus_bus_map(sc->sc_bustag,
sa->sa_reg[4].oa_space /* sa_slot */,
sa->sa_reg[4].oa_base /* sa_offset */,
sa->sa_reg[4].oa_size /* sa_size */,
BUS_SPACE_MAP_LINEAR,
&sc->sc_bhregs_regfile) != 0) {
aprint_error(": cannot map Jareth regfile\n");
sc->sc_has_jareth = 0;
} else {
aprint_normal_dev(self, "Jareth regfile @ %p\n", (void*)sc->sc_bhregs_regfile);
}
}
}
}
} else {
aprint_normal_dev(self, "Jareth not available\n");
}
goblinattach(sc, name, isconsole);
}

View File

@@ -48,9 +48,9 @@
#define GOBOFB_MODE_24BIT 0x10
#define GOBOFB_VBL_MASK_OFF 0x0
#define GOBOFB_VBL_MASK_ON 0x1
#define GOBOFB_VBL_MASK_ON 0x1
#define GOBOFB_VIDEOCTRL_OFF 0x0
#define GOBOFB_VIDEOCTRL_ON 0x3
#define GOBOFB_VIDEOCTRL_ON 0x1
#define GOBOFB_INTR_CLEAR_CLEAR 0x0

View File

@@ -51,6 +51,12 @@ struct goblin_softc {
bus_addr_t sc_reg_fbc_paddr; /* phys address for device mmap() */
bus_addr_t sc_fb_paddr; /* phys address for device mmap() */
uint32_t sc_size; /* full memory size */
int sc_opens; /* number of open() to track 8/24 bits */
int sc_has_jareth; /* whether we have a Jareth vector engine available */
bus_space_handle_t sc_bhregs_jareth; /* bus handle */
bus_space_handle_t sc_bhregs_microcode; /* bus handle */
bus_space_handle_t sc_bhregs_regfile; /* bus handle */
volatile struct goblin_fbcontrol *sc_fbc; /* control registers */
#if NWSDISPLAY > 0
@@ -58,9 +64,12 @@ struct goblin_softc {
uint32_t sc_height; /* display width / height */
uint32_t sc_stride;
int sc_mode;
struct vcons_data vd;
struct vcons_data sc_vd;
int sc_depth;
#endif
union bt_cmap sc_cmap; /* DAC color map */
};
#define GOBLIN_SET_PIXELMODE _IOW('M', 3, int)
void goblinattach(struct goblin_softc *, const char *, int);

View File

@@ -673,9 +673,26 @@ GOBLINValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags)
static Bool
GOBLINSaveScreen(ScreenPtr pScreen, int mode)
{
/* ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; */
/* GoblinPtr pGoblin = GET_GOBLIN_FROM_SCRN(pScrn); */
/* xf86Msg(X_INFO, "%s: %s\n", pGoblin->psdp->device, __PRETTY_FUNCTION__); */
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
GoblinPtr pGoblin = GET_GOBLIN_FROM_SCRN(pScrn);
/* xf86Msg(X_INFO, "%s: %s\n", pGoblin->psdp->device, __PRETTY_FUNCTION__); */
switch(mode)
{
case SCREEN_SAVER_ON:
case SCREEN_SAVER_CYCLE:
if (pGoblin->fbc->videoctrl != GOBOFB_VIDEOCTRL_OFF)
pGoblin->fbc->videoctrl = GOBOFB_VIDEOCTRL_OFF;
break;
case SCREEN_SAVER_OFF:
case SCREEN_SAVER_FORCER:
if (pGoblin->fbc->videoctrl != GOBOFB_VIDEOCTRL_ON)
pGoblin->fbc->videoctrl = GOBOFB_VIDEOCTRL_ON;
break;
default:
return FALSE;
}
return TRUE;
}

View File

@@ -45,11 +45,10 @@
#define GOBOFB_VBL_MASK_ON 0x1
#define GOBOFB_VIDEOCTRL_OFF 0x0
#define GOBOFB_VIDEOCTRL_ON 0x3
#define GOBOFB_VIDEOCTRL_ON 0x1
#define GOBOFB_INTR_CLEAR_CLEAR 0x0
typedef struct goblin_fbc {
uint32_t mode;
uint32_t vbl_mask;