summaryrefslogtreecommitdiff
path: root/sys/arch/sgi
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2007-12-31 12:46:15 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2007-12-31 12:46:15 +0000
commitf55c9af49ac20858a1ef9f84f24a11f26bec88ef (patch)
treeaeda19024b7aad741b2158e5dfabbde409ac6292 /sys/arch/sgi
parent5cb6f8c375209885c4063d6b91458743432837a5 (diff)
Significantly improve the gbe(4) driver, including:
- Internal restructure to separate code paths. - Add support for early console. This allows for gbe(4) to takeover were the ARCBios leaves off (if we should do so). - Add support for 8bpp and 16bpp colour depths. As a result, we also have support for colourmaps. We now use 8bpp as the default. - Add mmap() support, enabling wsfb to operate correctly. - Correct initial origin problem that occurred occasionally. ok miod@. tested by jasper@.
Diffstat (limited to 'sys/arch/sgi')
-rw-r--r--sys/arch/sgi/conf/files.sgi4
-rw-r--r--sys/arch/sgi/dev/gbe.c775
-rw-r--r--sys/arch/sgi/dev/gbereg.h45
-rw-r--r--sys/arch/sgi/sgi/wscons_machdep.c39
4 files changed, 636 insertions, 227 deletions
diff --git a/sys/arch/sgi/conf/files.sgi b/sys/arch/sgi/conf/files.sgi
index 16e6e00c067..bc321bafa9e 100644
--- a/sys/arch/sgi/conf/files.sgi
+++ b/sys/arch/sgi/conf/files.sgi
@@ -1,4 +1,4 @@
-# $OpenBSD: files.sgi,v 1.18 2007/12/31 11:42:43 jsing Exp $
+# $OpenBSD: files.sgi,v 1.19 2007/12/31 12:46:14 jsing Exp $
#
# maxpartitions must be first item in files.${ARCH}
#
@@ -87,7 +87,7 @@ file arch/sgi/sgi/clock_md.c clock
# GBE framebuffer
device gbe: wsemuldisplaydev, rasops8, rasops16, rasops32
attach gbe at mainbus
-file arch/sgi/dev/gbe.c gbe
+file arch/sgi/dev/gbe.c gbe needs-flag
# 16[45]50-based "com" ports on localbus
attach com at xbowmux with com_xbow
diff --git a/sys/arch/sgi/dev/gbe.c b/sys/arch/sgi/dev/gbe.c
index c55304e4c7a..d9939581ee5 100644
--- a/sys/arch/sgi/dev/gbe.c
+++ b/sys/arch/sgi/dev/gbe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gbe.c,v 1.3 2007/12/14 16:03:10 jsing Exp $ */
+/* $OpenBSD: gbe.c,v 1.4 2007/12/31 12:46:14 jsing Exp $ */
/*
* Copyright (c) 2007, Joel Sing <jsing@openbsd.org>
@@ -23,6 +23,9 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <sys/malloc.h>
+
+#include <uvm/uvm_extern.h>
#include <machine/autoconf.h>
#include <machine/bus.h>
@@ -39,46 +42,77 @@
#include "gbereg.h"
-struct gbe_softc {
- struct device sc_dev;
- struct rasops_info ri; /* Raster display info */
+/* Amount of memory to allocate for framebuffer. */
+#define GBE_FB_SIZE 8 * 1 << 20
- bus_space_tag_t iot;
- bus_space_handle_t ioh;
+/*
+ * Colourmap data.
+ */
+struct gbe_cmap {
+ u_int8_t cm_red[256];
+ u_int8_t cm_green[256];
+ u_int8_t cm_blue[256];
+};
- bus_dma_tag_t dmat;
+/*
+ * Screen data.
+ */
+struct gbe_screen {
+ struct device *sc; /* Back pointer. */
- bus_dmamap_t tm_dmamap;
- bus_dmamap_t fb_dmamap;
+ struct rasops_info ri; /* Raster display info. */
+ struct gbe_cmap cmap; /* Display colour map. */
- bus_dma_segment_t tm_segs[1];
- bus_dma_segment_t fb_segs[1];
+ int fb_size; /* Size of framebuffer memory. */
+ int tm_size; /* Size of tilemap memory. */
- int tm_nsegs;
- int fb_nsegs;
+ caddr_t tm; /* Address of tilemap memory. */
+ paddr_t tm_phys; /* Physical address of tilemap. */
+ caddr_t fb; /* Address of framebuffer memory. */
+ paddr_t fb_phys; /* Physical address of framebuffer. */
- int fb_size; /* Size of framebuffer memory */
- int tm_size; /* Size of tilemap memory */
+ int width; /* Width in pixels. */
+ int height; /* Height in pixels. */
+ int depth; /* Colour depth in bits. */
+ int linebytes; /* Bytes per line. */
+};
- caddr_t tilemap; /* Address of tilemap memory */
- caddr_t fb; /* Address of framebuffer memory */
+/*
+ * GBE device data.
+ */
+struct gbe_softc {
+ struct device sc_dev;
+
+ bus_space_tag_t iot;
+ bus_space_handle_t ioh;
+ bus_dma_tag_t dmat;
- int rev; /* Revision */
+ int rev; /* Hardware revision. */
int console; /* Is this the console? */
- int screens; /* No of screens allocated */
+ int screens; /* No of screens allocated. */
- int width; /* Width in pixels */
- int height; /* Height in pixels */
- int depth; /* Colour depth in bits */
- int linebytes; /* Bytes per line */
+ struct gbe_screen *curscr; /* Current screen. */
};
+/*
+ * Hardware and device related functions.
+ */
+void gbe_init_screen(struct gbe_screen *);
+void gbe_enable(struct gbe_softc *);
void gbe_disable(struct gbe_softc *);
+void gbe_setup(struct gbe_softc *);
+void gbe_setcolour(struct gbe_softc *, u_int, u_int8_t, u_int8_t, u_int8_t);
+
+/*
+ * Colour map handling for indexed modes.
+ */
+int gbe_getcmap(struct gbe_cmap *, struct wsdisplay_cmap *);
+int gbe_putcmap(struct gbe_cmap *, struct wsdisplay_cmap *);
+void gbe_loadcmap(struct gbe_screen *, u_int, u_int);
/*
* Interfaces for wscons.
*/
-
int gbe_ioctl(void *, u_long, caddr_t, int, struct proc *);
paddr_t gbe_mmap(void *, off_t, int);
int gbe_alloc_screen(void *, const struct wsscreen_descr *, void **,
@@ -88,8 +122,11 @@ int gbe_show_screen(void *, void *, int, void (*)(void *, int, int),
void *);
void gbe_burner(void *, u_int, u_int);
+static struct gbe_screen gbe_consdata;
+static int gbe_console;
+
struct wsscreen_descr gbe_stdscreen = {
- "std", /* Screen name */
+ "std", /* Screen name. */
};
struct wsdisplay_accessops gbe_accessops = {
@@ -138,24 +175,68 @@ void
gbe_attach(struct device *parent, struct device *self, void *aux)
{
struct gbe_softc *gsc = (void*)self;
+ struct gbe_screen *screen;
struct wsemuldisplaydev_attach_args waa;
- uint16_t *tm;
+ bus_dma_segment_t tm_segs[1];
+ bus_dma_segment_t fb_segs[1];
+ bus_dmamap_t tm_dmamap;
+ bus_dmamap_t fb_dmamap;
+ int tm_nsegs;
+ int fb_nsegs;
uint32_t val;
long attr;
- int i;
printf(": ");
/* GBE isn't strictly on the crimebus, but use this for now... */
gsc->iot = &crimebus_tag;
gsc->dmat = &mace_bus_dma_tag;
- gsc->console = 0;
+ gsc->console = gbe_console;
gsc->screens = 0;
+ if (gsc->console == 1) {
+
+ /*
+ * We've already been setup via gbe_cnattach().
+ */
+
+ gsc->ioh = PHYS_TO_XKPHYS(GBE_BASE, CCA_NC);
+ gsc->rev = bus_space_read_4(gsc->iot, gsc->ioh, GBE_CTRL_STAT)
+ & 0xf;
+
+ gsc->curscr = &gbe_consdata;
+ gbe_consdata.sc = (void*)self;
+
+ printf("rev %u, %iMB, %dx%d at %d bits\n", gsc->rev,
+ gbe_consdata.fb_size >> 20, gbe_consdata.width,
+ gbe_consdata.height, gbe_consdata.depth);
+
+ shutdownhook_establish((void(*)(void *))gbe_disable, self);
+
+ waa.console = gsc->console;
+ waa.scrdata = &gbe_screenlist;
+ waa.accessops = &gbe_accessops;
+ waa.accesscookie = &gbe_consdata;
+ config_found(self, &waa, wsemuldisplaydevprint);
+
+ return;
+ }
+
+ /*
+ * Setup screen data.
+ */
+ gsc->curscr = malloc(sizeof(struct gbe_screen), M_DEVBUF, M_NOWAIT);
+ if (gsc->curscr == NULL) {
+ printf("failed to allocate screen memory!\n");
+ return;
+ }
+ gsc->curscr->sc = (void *)gsc;
+ screen = gsc->curscr;
+
/*
* Setup bus space mapping.
*/
- if (bus_space_map(gsc->iot, GBE_BASE - CRIMEBUS_BASE, 0x100000,
+ if (bus_space_map(gsc->iot, GBE_BASE - CRIMEBUS_BASE, GBE_REG_SIZE,
BUS_SPACE_MAP_LINEAR, &gsc->ioh)) {
printf("failed to map bus space!\n");
return;
@@ -166,49 +247,44 @@ gbe_attach(struct device *parent, struct device *self, void *aux)
/* Determine resolution configured by firmware. */
val = bus_space_read_4(gsc->iot, gsc->ioh, GBE_VT_HCMAP);
- gsc->width = (val >> GBE_VT_HCMAP_ON_SHIFT) & 0xfff;
+ screen->width = (val >> GBE_VT_HCMAP_ON_SHIFT) & 0xfff;
val = bus_space_read_4(gsc->iot, gsc->ioh, GBE_VT_VCMAP);
- gsc->height = (val >> GBE_VT_VCMAP_ON_SHIFT) & 0xfff;
+ screen->height = (val >> GBE_VT_VCMAP_ON_SHIFT) & 0xfff;
- if (gsc->width == 0 || gsc->height == 0) {
+ if (screen->width == 0 || screen->height == 0) {
printf("device has not been setup by firmware!\n");
goto fail0;
}
- /* Determine colour depth configured by firmware. */
- val = bus_space_read_4(gsc->iot, gsc->ioh, GBE_FB_SIZE_TILE);
- gsc->depth = 0x8 << ((val >> GBE_FB_SIZE_TILE_DEPTH_SHIFT) & 0x3);
-
- /* XXX 8MB and 32bpp for now. */
- gsc->fb_size = 8 * 1024 * 1024;
- gsc->tm_size = GBE_TLB_SIZE * sizeof(uint16_t);
- gsc->depth = 32;
- gsc->linebytes = gsc->width * gsc->depth / 8;
+ /* Setup screen defaults. */
+ screen->fb_size = GBE_FB_SIZE;
+ screen->tm_size = GBE_TLB_SIZE * sizeof(uint16_t);
+ screen->depth = 8;
+ screen->linebytes = screen->width * screen->depth / 8;
/*
* Setup DMA for tile map.
*/
-
- if (bus_dmamap_create(gsc->dmat, gsc->tm_size, 1, gsc->tm_size, 0,
- BUS_DMA_NOWAIT, &gsc->tm_dmamap)) {
+ if (bus_dmamap_create(gsc->dmat, screen->tm_size, 1, screen->tm_size,
+ 0, BUS_DMA_NOWAIT, &tm_dmamap)) {
printf("failed to create DMA map for tile map!\n");
goto fail0;
}
- if (bus_dmamem_alloc(gsc->dmat, gsc->tm_size, 65536, 0, gsc->tm_segs, 1,
- &gsc->tm_nsegs, BUS_DMA_NOWAIT)) {
+ if (bus_dmamem_alloc(gsc->dmat, screen->tm_size, 65536, 0, tm_segs, 1,
+ &tm_nsegs, BUS_DMA_NOWAIT)) {
printf("failed to allocate DMA memory for tile map!\n");
goto fail1;
}
- if (bus_dmamem_map(gsc->dmat, gsc->tm_segs, gsc->tm_nsegs, gsc->tm_size,
- &gsc->tilemap, BUS_DMA_COHERENT)) {
+ if (bus_dmamem_map(gsc->dmat, tm_segs, tm_nsegs, screen->tm_size,
+ &screen->tm, BUS_DMA_COHERENT)) {
printf("failed to map DMA memory for tile map!\n");
goto fail2;
}
- if (bus_dmamap_load(gsc->dmat, gsc->tm_dmamap, gsc->tilemap,
- gsc->tm_size, NULL, BUS_DMA_NOWAIT)){
+ if (bus_dmamap_load(gsc->dmat, tm_dmamap, screen->tm, screen->tm_size,
+ NULL, BUS_DMA_NOWAIT)){
printf("failed to load DMA map for tilemap\n");
goto fail3;
}
@@ -216,55 +292,131 @@ gbe_attach(struct device *parent, struct device *self, void *aux)
/*
* Setup DMA for framebuffer.
*/
-
- if (bus_dmamap_create(gsc->dmat, gsc->fb_size, 1, gsc->fb_size, 0,
- BUS_DMA_NOWAIT, &gsc->fb_dmamap)) {
+ if (bus_dmamap_create(gsc->dmat, screen->fb_size, 1, screen->fb_size,
+ 0, BUS_DMA_NOWAIT, &fb_dmamap)) {
printf("failed to create DMA map for framebuffer!\n");
goto fail4;
}
- if (bus_dmamem_alloc(gsc->dmat, gsc->fb_size, 65536, 0, gsc->fb_segs,
- 1, &gsc->fb_nsegs, BUS_DMA_NOWAIT)) {
+ if (bus_dmamem_alloc(gsc->dmat, screen->fb_size, 65536, 0, fb_segs,
+ 1, &fb_nsegs, BUS_DMA_NOWAIT)) {
printf("failed to allocate DMA memory for framebuffer!\n");
goto fail5;
}
- if (bus_dmamem_map(gsc->dmat, gsc->fb_segs, gsc->fb_nsegs, gsc->fb_size,
- &gsc->fb, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) {
+ if (bus_dmamem_map(gsc->dmat, fb_segs, fb_nsegs, screen->fb_size,
+ &screen->fb, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) {
printf("failed to map DMA memory for framebuffer!\n");
goto fail6;
}
- if (bus_dmamap_load(gsc->dmat, gsc->fb_dmamap, gsc->fb, gsc->fb_size,
+ if (bus_dmamap_load(gsc->dmat, fb_dmamap, screen->fb, screen->fb_size,
NULL, BUS_DMA_NOWAIT)) {
printf("failed to load DMA map for framebuffer\n");
goto fail7;
}
+ screen->tm_phys = tm_dmamap->dm_segs[0].ds_addr;
+ screen->fb_phys = fb_dmamap->dm_segs[0].ds_addr;
+
shutdownhook_establish((void(*)(void *))gbe_disable, self);
+ gbe_init_screen(screen);
+ gbe_disable(gsc);
+ gbe_setup(gsc);
+ gbe_enable(gsc);
+
+ /* Load colourmap if required. */
+ if (screen->depth == 8)
+ gbe_loadcmap(screen, 0, 255);
+
+ printf("rev %u, %iMB, %dx%d at %d bits\n", gsc->rev,
+ screen->fb_size >> 20, screen->width, screen->height,
+ screen->depth);
+
+ /*
+ * Attach wsdisplay.
+ */
+
+ /* Attach as console if necessary. */
+ if (strncmp(bios_console, "video", 5) == 0) {
+ screen->ri.ri_ops.alloc_attr(&screen->ri, 0, 0, 0, &attr);
+ wsdisplay_cnattach(&gbe_stdscreen, &screen->ri, 0, 0, attr);
+ gsc->console = 1;
+ }
+
+ waa.console = gsc->console;
+ waa.scrdata = &gbe_screenlist;
+ waa.accessops = &gbe_accessops;
+ waa.accesscookie = screen;
+ config_found(self, &waa, wsemuldisplaydevprint);
+
+ return;
+
+fail7:
+ bus_dmamem_unmap(gsc->dmat, screen->fb, screen->fb_size);
+fail6:
+ bus_dmamem_free(gsc->dmat, fb_segs, fb_nsegs);
+fail5:
+ bus_dmamap_destroy(gsc->dmat, fb_dmamap);
+fail4:
+ bus_dmamap_unload(gsc->dmat, tm_dmamap);
+fail3:
+ bus_dmamem_unmap(gsc->dmat, screen->tm, screen->tm_size);
+fail2:
+ bus_dmamem_free(gsc->dmat, tm_segs, tm_nsegs);
+fail1:
+ bus_dmamap_destroy(gsc->dmat, tm_dmamap);
+fail0:
+ bus_space_unmap(gsc->iot, gsc->ioh, GBE_REG_SIZE);
+}
+
+/*
+ * GBE hardware specific functions.
+ */
+
+void
+gbe_init_screen(struct gbe_screen *screen)
+{
+ uint16_t *tm;
+ int i;
+
/*
* Initialise rasops.
*/
- memset(&gsc->ri, 0, sizeof(struct rasops_info));
-
- gsc->ri.ri_flg = RI_CENTER | RI_CLEAR;
- gsc->ri.ri_depth = gsc->depth;
- gsc->ri.ri_width = gsc->width;
- gsc->ri.ri_height = gsc->height;
- gsc->ri.ri_bits = (void *)gsc->fb;
- gsc->ri.ri_stride = gsc->linebytes;
-
- if (gsc->depth == 32) {
- gsc->ri.ri_rpos = 24;
- gsc->ri.ri_rnum = 8;
- gsc->ri.ri_gpos = 16;
- gsc->ri.ri_gnum = 8;
- gsc->ri.ri_bpos = 8;
- gsc->ri.ri_bnum = 8;
+ memset(&screen->ri, 0, sizeof(struct rasops_info));
+
+ screen->ri.ri_flg = RI_CENTER | RI_CLEAR;
+ screen->ri.ri_depth = screen->depth;
+ screen->ri.ri_width = screen->width;
+ screen->ri.ri_height = screen->height;
+ screen->ri.ri_bits = (void *)screen->fb;
+ screen->ri.ri_stride = screen->linebytes;
+
+ if (screen->depth == 32) {
+ screen->ri.ri_rpos = 24;
+ screen->ri.ri_rnum = 8;
+ screen->ri.ri_gpos = 16;
+ screen->ri.ri_gnum = 8;
+ screen->ri.ri_bpos = 8;
+ screen->ri.ri_bnum = 8;
+ } else if (screen->depth == 16) {
+ screen->ri.ri_rpos = 10;
+ screen->ri.ri_rnum = 5;
+ screen->ri.ri_gpos = 5;
+ screen->ri.ri_gnum = 5;
+ screen->ri.ri_bpos = 0;
+ screen->ri.ri_bnum = 5;
}
- rasops_init(&gsc->ri, gsc->height / 8, gsc->width / 8);
+ rasops_init(&screen->ri, screen->height / 8, screen->width / 8);
+
+ gbe_stdscreen.ncols = screen->ri.ri_cols;
+ gbe_stdscreen.nrows = screen->ri.ri_rows;
+ gbe_stdscreen.textops = &screen->ri.ri_ops;
+ gbe_stdscreen.fontwidth = screen->ri.ri_font->fontwidth;
+ gbe_stdscreen.fontheight = screen->ri.ri_font->fontheight;
+ gbe_stdscreen.capabilities = screen->ri.ri_caps;
/*
* Map framebuffer into tile map. Each entry in the tilemap is 16 bits
@@ -273,46 +425,130 @@ gbe_attach(struct device *parent, struct device *self, void *aux)
* discard the lower 16 bits and store bits 17 through 32 as an entry
* in the tilemap.
*/
- tm = (void *)gsc->tilemap;
- for (i = 0; i < (gsc->fb_size >> GBE_TILE_SHIFT); i++)
- tm[i] = (gsc->fb_dmamap->dm_segs[0].ds_addr >> GBE_TILE_SHIFT) + i;
+ tm = (void *)screen->tm;
+ for (i = 0; i < (screen->fb_size >> GBE_TILE_SHIFT); i++)
+ tm[i] = (screen->fb_phys >> GBE_TILE_SHIFT) + i;
+}
+
+void
+gbe_enable(struct gbe_softc *gsc)
+{
+ struct gbe_screen *screen = gsc->curscr;
+ uint32_t val;
+ int i;
+
+ /* Enable dot clock. */
+ val = bus_space_read_4(gsc->iot, gsc->ioh, GBE_DOTCLOCK);
+ bus_space_write_4(gsc->iot, gsc->ioh, GBE_DOTCLOCK,
+ val | GBE_DOTCLOCK_RUN);
+ for (i = 0; i < 10000; i++) {
+ val = bus_space_read_4(gsc->iot, gsc->ioh, GBE_DOTCLOCK);
+ if ((val & GBE_DOTCLOCK_RUN) == GBE_DOTCLOCK_RUN)
+ break;
+ delay(10);
+ }
+ if (i == 10000)
+ printf("timeout enabling dot clock!\n");
+
+ /* Unfreeze pixel counter. */
+ bus_space_write_4(gsc->iot, gsc->ioh, GBE_VT_XY, 0);
+ for (i = 0; i < 10000; i++) {
+ val = bus_space_read_4(gsc->iot, gsc->ioh, GBE_VT_XY);
+ if ((val & GBE_VT_XY_FREEZE) == 0)
+ break;
+ delay(10);
+ }
+ if (i == 10000)
+ printf("timeout unfreezing pixel counter!\n");
+
+ /* Provide GBE with address of tile map and enable DMA. */
+ bus_space_write_4(gsc->iot, gsc->ioh, GBE_FB_CTRL,
+ ((screen->tm_phys >> 9) <<
+ GBE_FB_CTRL_TILE_PTR_SHIFT) | GBE_FB_CTRL_DMA_ENABLE);
+}
+
+void
+gbe_disable(struct gbe_softc *gsc)
+{
+ uint32_t val;
+ int i;
+
+ /* Nothing to do if the pixel counter is frozen! */
+ val = bus_space_read_4(gsc->iot, gsc->ioh, GBE_VT_XY);
+ if ((val & GBE_VT_XY_FREEZE) == GBE_VT_XY_FREEZE)
+ return;
+
+ val = bus_space_read_4(gsc->iot, gsc->ioh, GBE_DOTCLOCK);
+ if ((val & GBE_DOTCLOCK_RUN) == 0)
+ return;
+
+ /* Disable overlay and turn off hardware cursor. */
+ bus_space_write_4(gsc->iot, gsc->ioh, GBE_OVERLAY_TILE, 0);
+ bus_space_write_4(gsc->iot, gsc->ioh, GBE_CURSOR_CTRL, 0);
+ bus_space_write_4(gsc->iot, gsc->ioh, GBE_DID_CTRL, 0);
/* Disable DMA. */
val = bus_space_read_4(gsc->iot, gsc->ioh, GBE_OVERLAY_CTRL);
bus_space_write_4(gsc->iot, gsc->ioh, GBE_OVERLAY_CTRL,
val & ~GBE_OVERLAY_CTRL_DMA_ENABLE);
- delay(1000);
val = bus_space_read_4(gsc->iot, gsc->ioh, GBE_FB_CTRL);
bus_space_write_4(gsc->iot, gsc->ioh, GBE_FB_CTRL,
val & ~GBE_FB_CTRL_DMA_ENABLE);
- delay(1000);
bus_space_write_4(gsc->iot, gsc->ioh, GBE_DID_CTRL, 0);
- delay(1000);
+ for (i = 0; i < 100000; i++) {
+ if ((bus_space_read_4(gsc->iot, gsc->ioh, GBE_OVERLAY_HW_CTRL)
+ & GBE_OVERLAY_CTRL_DMA_ENABLE) == 0 &&
+ (bus_space_read_4(gsc->iot, gsc->ioh, GBE_FB_HW_CTRL)
+ & GBE_FB_CTRL_DMA_ENABLE) == 0 &&
+ bus_space_read_4(gsc->iot, gsc->ioh, GBE_DID_HW_CTRL) == 0)
+ break;
+ delay(10);
+ }
+ if (i == 100000)
+ printf("timeout disabling DMA!\n");
+
+ /* Wait for the end of pixel refresh. */
+ val = bus_space_read_4(gsc->iot, gsc->ioh, GBE_VT_VPIX)
+ & GBE_VT_VPIX_OFF_MASK;
+ for (i = 0; i < 100000; i++) {
+ if (((bus_space_read_4(gsc->iot, gsc->ioh, GBE_VT_XY)
+ & GBE_VT_XY_Y_MASK) >> GBE_VT_XY_Y_SHIFT) < val)
+ break;
+ delay(1);
+ }
+ if (i == 100000)
+ printf("timeout waiting for pixel refresh!\n");
+ for (i = 0; i < 100000; i++) {
+ if (((bus_space_read_4(gsc->iot, gsc->ioh, GBE_VT_XY)
+ & GBE_VT_XY_Y_MASK) >> GBE_VT_XY_Y_SHIFT) > val)
+ break;
+ delay(1);
+ }
+ if (i == 100000)
+ printf("timeout waiting for pixel refresh!\n");
/* Freeze pixel counter. */
bus_space_write_4(gsc->iot, gsc->ioh, GBE_VT_XY, GBE_VT_XY_FREEZE);
- delay(10000);
- for (i = 0; i < 10000; i++) {
+ for (i = 0; i < 100000; i++) {
val = bus_space_read_4(gsc->iot, gsc->ioh, GBE_VT_XY);
if ((val & GBE_VT_XY_FREEZE) == GBE_VT_XY_FREEZE)
break;
delay(10);
}
- if (i == 10000)
+ if (i == 100000)
printf("timeout freezing pixel counter!\n");
/* Disable dot clock. */
val = bus_space_read_4(gsc->iot, gsc->ioh, GBE_DOTCLOCK);
bus_space_write_4(gsc->iot, gsc->ioh, GBE_DOTCLOCK,
val & ~GBE_DOTCLOCK_RUN);
- delay(10000);
- for (i = 0; i < 10000; i++) {
+ for (i = 0; i < 100000; i++) {
val = bus_space_read_4(gsc->iot, gsc->ioh, GBE_DOTCLOCK);
if ((val & GBE_DOTCLOCK_RUN) == 0)
break;
delay(10);
}
- if (i == 10000)
+ if (i == 100000)
printf("timeout disabling dot clock!\n");
/* Reset DMA fifo. */
@@ -321,115 +557,71 @@ gbe_attach(struct device *parent, struct device *self, void *aux)
bus_space_write_4(gsc->iot, gsc->ioh, GBE_FB_SIZE_TILE,
val | (1 << GBE_FB_SIZE_TILE_FIFO_RESET_SHIFT));
bus_space_write_4(gsc->iot, gsc->ioh, GBE_FB_SIZE_TILE, val);
+}
- /* Disable overlay and turn off hardware cursor. */
- bus_space_write_4(gsc->iot, gsc->ioh, GBE_OVERLAY_TILE, 0);
- bus_space_write_4(gsc->iot, gsc->ioh, GBE_CURSOR_CTRL, 0);
- bus_space_write_4(gsc->iot, gsc->ioh, GBE_DID_CTRL, 0);
+void
+gbe_setup(struct gbe_softc *gsc)
+{
+ struct gbe_screen *screen = gsc->curscr;
+ uint32_t val;
+ int i, cmode;
+ u_char *colour;
+
+ /*
+ * Setup framebuffer.
+ */
+ switch (screen->depth) {
+ case 32:
+ cmode = GBE_CMODE_RGB8;
+ break;
+ case 16:
+ cmode = GBE_CMODE_ARGB5;
+ break;
+ case 8:
+ default:
+ cmode = GBE_CMODE_I8;
+ break;
+ }
/* Trick framebuffer into linear mode. */
- i = gsc->width * gsc->height / (512 / (gsc->depth >> 3));
+ i = screen->width * screen->height / (512 / (screen->depth >> 3));
bus_space_write_4(gsc->iot, gsc->ioh, GBE_FB_SIZE_PIXEL,
i << GBE_FB_SIZE_PIXEL_HEIGHT_SHIFT);
- /* Setup framebuffer - fixed at 32bpp for now. */
bus_space_write_4(gsc->iot, gsc->ioh, GBE_FB_SIZE_TILE,
(1 << GBE_FB_SIZE_TILE_WIDTH_SHIFT) |
- (GBE_FB_DEPTH_32 << GBE_FB_SIZE_TILE_DEPTH_SHIFT));
- val = (GBE_CMODE_RGB8 << GBE_WID_MODE_SHIFT) | GBE_BMODE_BOTH;
+ ((screen->depth >> 4) << GBE_FB_SIZE_TILE_DEPTH_SHIFT));
+
+ val = (cmode << GBE_WID_MODE_SHIFT) | GBE_BMODE_BOTH;
for (i = 0; i < (32 * 4); i += 4)
bus_space_write_4(gsc->iot, gsc->ioh, GBE_MODE + i, val);
- /* Enable dot clock. */
- val = bus_space_read_4(gsc->iot, gsc->ioh, GBE_DOTCLOCK);
- bus_space_write_4(gsc->iot, gsc->ioh, GBE_DOTCLOCK,
- val | GBE_DOTCLOCK_RUN);
- delay(10000);
- for (i = 0; i < 10000; i++) {
- val = bus_space_read_4(gsc->iot, gsc->ioh, GBE_DOTCLOCK);
- if ((val & GBE_DOTCLOCK_RUN) == GBE_DOTCLOCK_RUN)
- break;
- delay(10);
- }
- if (i == 10000)
- printf("timeout enabling dot clock!\n");
-
- /* Unfreeze pixel counter. */
- bus_space_write_4(gsc->iot, gsc->ioh, GBE_VT_XY, 0);
- delay(10000);
- for (i = 0; i < 10000; i++) {
- val = bus_space_read_4(gsc->iot, gsc->ioh, GBE_VT_XY);
- if ((val & GBE_VT_XY_FREEZE) == 0)
- break;
- delay(10);
- }
- if (i == 10000)
- printf("timeout unfreezing pixel counter!\n");
-
- /* Provide GBE with address of tile map and enable DMA. */
- bus_space_write_4(gsc->iot, gsc->ioh, GBE_FB_CTRL,
- ((gsc->tm_dmamap->dm_segs[0].ds_addr >> 9) <<
- GBE_FB_CTRL_TILE_PTR_SHIFT) | GBE_FB_CTRL_DMA_ENABLE);
-
- printf("rev %u, %iMB, %dx%d at %d bits\n", gsc->rev, gsc->fb_size >> 20,
- gsc->width, gsc->height, gsc->depth);
-
/*
- * Setup default screen and attach wsdisplay.
+ * Initialise colourmap if required.
*/
-
- gbe_stdscreen.ncols = gsc->ri.ri_cols;
- gbe_stdscreen.nrows = gsc->ri.ri_rows;
- gbe_stdscreen.textops = &gsc->ri.ri_ops;
- gbe_stdscreen.fontwidth = gsc->ri.ri_font->fontwidth;
- gbe_stdscreen.fontheight = gsc->ri.ri_font->fontheight;
- gbe_stdscreen.capabilities = gsc->ri.ri_caps;
-
- /* Attach as console if necessary. */
- if (strncmp(bios_console, "video", 5) == 0) {
- gsc->ri.ri_ops.alloc_attr(&gsc->ri, 0, 0, 0, &attr);
- wsdisplay_cnattach(&gbe_stdscreen, &gsc->ri, 0, 0, attr);
- gsc->console = 1;
+ if (screen->depth == 8) {
+ for (i = 0; i < 16; i++) {
+ colour = (u_char *)&rasops_cmap[i * 3];
+ screen->cmap.cm_red[i] = colour[0];
+ screen->cmap.cm_green[i] = colour[1];
+ screen->cmap.cm_blue[i] = colour[2];
+ }
+ for (i = 240; i < 256; i++) {
+ colour = (u_char *)&rasops_cmap[i * 3];
+ screen->cmap.cm_red[i] = colour[0];
+ screen->cmap.cm_green[i] = colour[1];
+ screen->cmap.cm_blue[i] = colour[2];
+ }
}
- waa.console = gsc->console;
- waa.scrdata = &gbe_screenlist;
- waa.accessops = &gbe_accessops;
- waa.accesscookie = self;
- config_found(self, &waa, wsemuldisplaydevprint);
-
- return;
+ /*
+ * Setup an alpha ramp.
+ */
+ for (i = 0; i < GBE_GMAP_ENTRIES; i++)
+ bus_space_write_4(gsc->iot, gsc->ioh,
+ GBE_GMAP + i * sizeof(u_int32_t),
+ (i << 24) | (i << 16) | (i << 8));
-fail7:
- bus_dmamem_unmap(gsc->dmat, gsc->fb, gsc->fb_size);
-fail6:
- bus_dmamem_free(gsc->dmat, gsc->fb_segs, gsc->fb_nsegs);
-fail5:
- bus_dmamap_destroy(gsc->dmat, gsc->fb_dmamap);
-fail4:
- bus_dmamap_unload(gsc->dmat, gsc->tm_dmamap);
-fail3:
- bus_dmamem_unmap(gsc->dmat, gsc->tilemap, gsc->tm_size);
-fail2:
- bus_dmamem_free(gsc->dmat, gsc->tm_segs, gsc->tm_nsegs);
-fail1:
- bus_dmamap_destroy(gsc->dmat, gsc->tm_dmamap);
-fail0:
- bus_space_unmap(gsc->iot, gsc->ioh, 0x100000);
-}
-
-/*
- * GBE hardware specific functions.
- */
-
-void
-gbe_disable(struct gbe_softc *gsc)
-{
- uint32_t val;
-
- val = bus_space_read_4(gsc->iot, gsc->ioh, GBE_FB_CTRL);
- bus_space_write_4(gsc->iot, gsc->ioh, GBE_FB_CTRL,
- val & ~GBE_FB_CTRL_DMA_ENABLE);
}
/*
@@ -439,7 +631,8 @@ gbe_disable(struct gbe_softc *gsc)
int
gbe_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
{
- struct gbe_softc *gsc = (struct gbe_softc *)v;
+ struct gbe_screen *screen = (struct gbe_screen *)v;
+ int rc;
switch (cmd) {
case WSDISPLAYIO_GTYPE:
@@ -450,41 +643,37 @@ gbe_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
{
struct wsdisplay_fbinfo *fb = (struct wsdisplay_fbinfo *)data;
- fb->height = gsc->height;
- fb->width = gsc->width;
- fb->depth = gsc->depth;
- fb->cmsize = gsc->depth == 8 ? 256 : 0;
+ fb->height = screen->height;
+ fb->width = screen->width;
+ fb->depth = screen->depth;
+ fb->cmsize = screen->depth == 8 ? 256 : 0;
}
break;
case WSDISPLAYIO_LINEBYTES:
- *(u_int *)data = gsc->linebytes;
+ *(u_int *)data = screen->linebytes;
break;
case WSDISPLAYIO_GETCMAP:
- if (gsc->depth == 8) {
-#ifdef notyet
+ if (screen->depth == 8) {
struct wsdisplay_cmap *cm =
(struct wsdisplay_cmap *)data;
- rc = gbe_getcmap(&scr->scr_cmap, cm);
+ rc = gbe_getcmap(&screen->cmap, cm);
if (rc != 0)
return (rc);
-#endif
}
break;
case WSDISPLAYIO_PUTCMAP:
- if (gsc->depth == 8) {
-#ifdef notyet
+ if (screen->depth == 8) {
struct wsdisplay_cmap *cm =
(struct wsdisplay_cmap *)data;
- rc = gbe_putcmap(&scr->scr_cmap, cm);
+ rc = gbe_putcmap(&screen->cmap, cm);
if (rc != 0)
return (rc);
- gbe_loadcmap(sc, cm->index, cm->index + cm->count);
-#endif
+ gbe_loadcmap(screen, cm->index, cm->index + cm->count);
}
break;
@@ -503,15 +692,23 @@ gbe_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
paddr_t
gbe_mmap(void *v, off_t offset, int protection)
{
- /* Not at the moment. */
- return (-1);
+ struct gbe_screen *screen = (void *)v;
+ paddr_t pa;
+
+ if (offset >= 0 && offset < screen->fb_size)
+ pa = atop(screen->fb_phys + offset);
+ else
+ pa = -1;
+
+ return (pa);
}
int
gbe_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
int *curxp, int *curyp, long *attrp)
{
- struct gbe_softc *gsc = (struct gbe_softc *)v;
+ struct gbe_screen *screen = (struct gbe_screen *)v;
+ struct gbe_softc *gsc = (struct gbe_softc *)screen->sc;
/* We do not allow multiple consoles at the moment. */
if (gsc->screens > 0)
@@ -520,16 +717,16 @@ gbe_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
gsc->screens++;
/* Return rasops_info via cookie. */
- *cookiep = &gsc->ri;
+ *cookiep = &screen->ri;
/* Move cursor to top left of screen. */
*curxp = 0;
*curyp = 0;
/* Correct screen attributes. */
- gsc->ri.ri_ops.alloc_attr(&gsc->ri, 0, 0, 0, attrp);
+ screen->ri.ri_ops.alloc_attr(&screen->ri, 0, 0, 0, attrp);
- return 0;
+ return (0);
}
void
@@ -550,3 +747,179 @@ void
gbe_burner(void *v, u_int on, u_int flags)
{
}
+
+/*
+ * Colour map handling for indexed modes.
+ */
+
+void
+gbe_setcolour(struct gbe_softc *gsc, u_int index, u_int8_t r, u_int8_t g,
+ u_int8_t b)
+{
+ int i;
+
+ /* Wait until the colourmap FIFO has free space. */
+ for (i = 0; i < 10000; i++) {
+ if (bus_space_read_4(gsc->iot, gsc->ioh, GBE_CMAP_FIFO)
+ < GBE_CMAP_FIFO_ENTRIES)
+ break;
+ delay(10);
+ }
+ if (i == 10000)
+ printf("colourmap FIFO has no free space!\n");
+
+ bus_space_write_4(gsc->iot, gsc->ioh,
+ GBE_CMAP + index * sizeof(u_int32_t),
+ ((u_int)r << 24) | ((u_int)g << 16) | ((u_int)b << 8));
+}
+
+int
+gbe_getcmap(struct gbe_cmap *cm, struct wsdisplay_cmap *rcm)
+{
+ u_int index = rcm->index, count = rcm->count;
+ int rc;
+
+ if (index >= 256 || count > 256 - index)
+ return (EINVAL);
+
+ if ((rc = copyout(&cm->cm_red[index], rcm->red, count)) != 0)
+ return (rc);
+ if ((rc = copyout(&cm->cm_green[index], rcm->green, count)) != 0)
+ return (rc);
+ if ((rc = copyout(&cm->cm_blue[index], rcm->blue, count)) != 0)
+ return (rc);
+
+ return (0);
+}
+
+int
+gbe_putcmap(struct gbe_cmap *cm, struct wsdisplay_cmap *rcm)
+{
+ u_int index = rcm->index, count = rcm->count;
+ int rc;
+
+ if (index >= 256 || count > 256 - index)
+ return (EINVAL);
+
+ if ((rc = copyin(rcm->red, &cm->cm_red[index], count)) != 0)
+ return (rc);
+ if ((rc = copyin(rcm->green, &cm->cm_green[index], count)) != 0)
+ return (rc);
+ if ((rc = copyin(rcm->blue, &cm->cm_blue[index], count)) != 0)
+ return (rc);
+
+ return (0);
+}
+
+void
+gbe_loadcmap(struct gbe_screen *screen, u_int start, u_int end)
+{
+ struct gbe_softc *gsc = (void *)screen->sc;
+ struct gbe_cmap *cm = &screen->cmap;
+
+ for (; start <= end; start++)
+ gbe_setcolour(gsc, start,
+ cm->cm_red[start], cm->cm_green[start], cm->cm_blue[start]);
+}
+
+/*
+ * Console functions for early display.
+ */
+
+int
+gbe_cnprobe(bus_space_tag_t iot, bus_addr_t addr)
+{
+ bus_space_handle_t ioh;
+ int val, width, height;
+
+ /* Setup bus space mapping. */
+ ioh = PHYS_TO_XKPHYS(addr, CCA_NC);
+
+ /* Determine resolution configured by firmware. */
+ val = bus_space_read_4(iot, ioh, GBE_VT_HCMAP);
+ width = (val >> GBE_VT_HCMAP_ON_SHIFT) & 0xfff;
+ val = bus_space_read_4(iot, ioh, GBE_VT_VCMAP);
+ height = (val >> GBE_VT_VCMAP_ON_SHIFT) & 0xfff;
+
+ /* Ensure that the firmware has setup the device. */
+ if (width != 0 && height != 0)
+ return (1);
+ else
+ return (0);
+}
+
+int
+gbe_cnattach(bus_space_tag_t iot, bus_addr_t addr)
+{
+ struct gbe_softc gsc;
+ vaddr_t va;
+ paddr_t pa;
+ uint32_t val;
+ long attr;
+
+ /*
+ * Setup GBE for use as early console.
+ */
+ gsc.curscr = &gbe_consdata;
+ gbe_consdata.sc = (void *)&gsc;
+
+ /* Setup bus space mapping. */
+ gsc.iot = iot;
+ gsc.ioh = PHYS_TO_XKPHYS(addr, CCA_NC);
+
+ /* Determine GBE revision. */
+ gsc.rev = bus_space_read_4(gsc.iot, gsc.ioh, GBE_CTRL_STAT) & 0xf;
+
+ /* Determine resolution configured by firmware. */
+ val = bus_space_read_4(gsc.iot, gsc.ioh, GBE_VT_HCMAP);
+ gbe_consdata.width = (val >> GBE_VT_HCMAP_ON_SHIFT) & 0xfff;
+ val = bus_space_read_4(gsc.iot, gsc.ioh, GBE_VT_VCMAP);
+ gbe_consdata.height = (val >> GBE_VT_VCMAP_ON_SHIFT) & 0xfff;
+
+ /* Ensure that the firmware has setup the device. */
+ if (gbe_consdata.width == 0 || gbe_consdata.height == 0)
+ return (ENXIO);
+
+ /* Setup screen defaults. */
+ gbe_consdata.fb_size = GBE_FB_SIZE;
+ gbe_consdata.tm_size = GBE_TLB_SIZE * sizeof(uint16_t);
+ gbe_consdata.depth = 8;
+ gbe_consdata.linebytes = gbe_consdata.width * gbe_consdata.depth / 8;
+
+ /*
+ * Steal memory for tilemap - 64KB aligned and coherent.
+ */
+ va = pmap_steal_memory(gbe_consdata.tm_size + 65536, NULL, NULL);
+ pmap_extract(pmap_kernel(), va, &pa);
+ gbe_consdata.tm_phys = ((pa >> 16) + 1) << 16;
+ gbe_consdata.tm = (caddr_t)PHYS_TO_XKPHYS(gbe_consdata.tm_phys, CCA_NC);
+
+ /*
+ * Steal memory for framebuffer - 64KB aligned and coherent.
+ */
+ va = pmap_steal_memory(gbe_consdata.fb_size + 65536, NULL, NULL);
+ pmap_extract(pmap_kernel(), va, &pa);
+ gbe_consdata.fb_phys = ((pa >> 16) + 1) << 16;
+ gbe_consdata.fb = (caddr_t)PHYS_TO_XKPHYS(gbe_consdata.fb_phys, CCA_NC);
+
+ /*
+ * Setup GBE hardware.
+ */
+ gbe_init_screen(&gbe_consdata);
+ gbe_disable(&gsc);
+ gbe_setup(&gsc);
+ gbe_enable(&gsc);
+
+ /* Load colourmap if required. */
+ if (gbe_consdata.depth == 8)
+ gbe_loadcmap(&gbe_consdata, 0, 255);
+
+ /*
+ * Attach wsdisplay.
+ */
+ gbe_consdata.ri.ri_ops.alloc_attr(&gbe_consdata.ri, 0, 0, 0, &attr);
+ wsdisplay_cnattach(&gbe_stdscreen, &gbe_consdata.ri, 0, 0, attr);
+ gbe_console = 1;
+
+ return (1);
+}
diff --git a/sys/arch/sgi/dev/gbereg.h b/sys/arch/sgi/dev/gbereg.h
index 312e908ae02..b75fc7495e3 100644
--- a/sys/arch/sgi/dev/gbereg.h
+++ b/sys/arch/sgi/dev/gbereg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: gbereg.h,v 1.2 2007/11/27 16:08:06 jasper Exp $ */
+/* $OpenBSD: gbereg.h,v 1.3 2007/12/31 12:46:14 jsing Exp $ */
/*
* Copyright (c) 2007, Joel Sing <jsing@openbsd.org>
@@ -21,6 +21,7 @@
*/
#define GBE_BASE 0x16000000
+#define GBE_REG_SIZE 0x100000
#define GBE_TLB_SIZE 128
#define GBE_TILE_SHIFT 16
@@ -34,6 +35,10 @@
#define GBE_DOTCLOCK 0x00000004 /* Dotclock */
#define GBE_DOTCLOCK_RUN 0x00100000 /* Enable dotclock */
#define GBE_VT_XY 0x00010000 /* Current dot coordinates */
+#define GBE_VT_XY_X_SHIFT 0
+#define GBE_VT_XY_X_MASK 0x00000fff
+#define GBE_VT_XY_Y_SHIFT 12
+#define GBE_VT_XY_Y_MASK 0x00fff000
#define GBE_VT_XY_FREEZE 0x80000000 /* Freeze pixel counter */
#define GBE_VT_MAXXY 0x00010004 /* */
#define GBE_VT_VSYNC 0x00010008 /* Vertical sync on/off */
@@ -42,8 +47,12 @@
#define GBE_VT_HBLANK 0x00010014 /* Horizontal blanking */
#define GBE_VT_FLAGS 0x00010018 /* Video timing flags */
#define GBE_VT_SYNC_LOW 0x00000010 /* Sync on green */
-#define GBE_VT_HPIXEN 0x00010034 /* Horizontal pixel on/off */
-#define GBE_VT_VPIXEN 0x00010038 /* Vertical pixel on/off */
+#define GBE_VT_HPIX 0x00010034 /* Horizontal pixel on/off */
+#define GBE_VT_VPIX 0x00010038 /* Vertical pixel on/off */
+#define GBE_VT_VPIX_OFF_MASK 0x00000fff
+#define GBE_VT_VPIX_OFF_SHIFT 0
+#define GBE_VT_VPIX_ON_MASK 0x00fff000
+#define GBE_VT_VPIX_ON_SHIFT 12
#define GBE_VT_HCMAP 0x0001003c /* Horizontal cmap write */
#define GBE_VT_HCMAP_ON_SHIFT 12
#define GBE_VT_VCMAP 0x00010040 /* Vertical cmap write */
@@ -61,12 +70,20 @@
#define GBE_FB_SIZE_TILE_FIFO_RESET_SHIFT 15
#define GBE_FB_SIZE_PIXEL 0x00030004 /* Framebuffer - pixel size */
#define GBE_FB_SIZE_PIXEL_HEIGHT_SHIFT 16
+#define GBE_FB_HW_CTRL 0x00030008 /* Framebuffer - hardware control */
#define GBE_FB_CTRL 0x0003000c /* Framebuffer - control */
#define GBE_FB_CTRL_TILE_PTR_SHIFT 9
#define GBE_FB_CTRL_DMA_ENABLE 0x00000001
+#define GBE_DID_HW_CTRL 0x00040000 /* DID hardware control */
#define GBE_DID_CTRL 0x00040004 /* DID control */
#define GBE_MODE 0x00048000 /* Colour mode */
#define GBE_WID_MODE_SHIFT 2
+#define GBE_CMAP 0x050000 /* Colourmap */
+#define GBE_CMAP_ENTRIES 6144
+#define GBE_CMAP_FIFO 0x058000 /* Colourmap FIFO status */
+#define GBE_CMAP_FIFO_ENTRIES 63
+#define GBE_GMAP 0x060000 /* Gammamap */
+#define GBE_GMAP_ENTRIES 256
#define GBE_CURSOR_POS 0x00070000 /* Cursor position */
#define GBE_CURSOR_CTRL 0x00070004 /* Cursor control */
@@ -78,13 +95,19 @@
#define GBE_FB_DEPTH_16 1
#define GBE_FB_DEPTH_32 2
-#define GBE_CMODE_I8 0
-#define GBE_CMODE_I12 1
-#define GBE_CMODE_RG3B2 2
-#define GBE_CMODE_RGB4 3
-#define GBE_CMODE_ARGB5 4
-#define GBE_CMODE_RGB8 5
-#define GBE_CMODE_RGBA5 6
-#define GBE_CMODE_RGB10 7
+#define GBE_CMODE_I8 0 /* 8 bit indexed */
+#define GBE_CMODE_I12 1 /* 12 bit indexed */
+#define GBE_CMODE_RG3B2 2 /* 3:3:2 direct */
+#define GBE_CMODE_RGB4 3 /* 4:4:4 direct */
+#define GBE_CMODE_ARGB5 4 /* 1:5:5:5 direct */
+#define GBE_CMODE_RGB8 5 /* 8:8:8 direct */
+#define GBE_CMODE_RGBA5 6 /* 5:5:5:5 direct */
+#define GBE_CMODE_RGB10 7 /* 10:10:10 direct */
#define GBE_BMODE_BOTH 3
+
+/*
+ * Console functions.
+ */
+int gbe_cnprobe(bus_space_tag_t, bus_addr_t addr);
+int gbe_cnattach(bus_space_tag_t, bus_addr_t addr);
diff --git a/sys/arch/sgi/sgi/wscons_machdep.c b/sys/arch/sgi/sgi/wscons_machdep.c
index 43e9acfb6dd..ebe0b187aa8 100644
--- a/sys/arch/sgi/sgi/wscons_machdep.c
+++ b/sys/arch/sgi/sgi/wscons_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wscons_machdep.c,v 1.1 2007/12/31 11:42:43 jsing Exp $ */
+/* $OpenBSD: wscons_machdep.c,v 1.2 2007/12/31 12:46:14 jsing Exp $ */
/*
* Copyright (c) 2001 Aaron Campbell
@@ -37,16 +37,21 @@
#include <machine/bus.h>
#include <mips64/arcbios.h>
+#include <mips64/archtype.h>
-#include <sgi/dev/mkbcreg.h>
+#include <sgi/localbus/crimebus.h>
#include <sgi/localbus/macebus.h>
+#include <sgi/dev/gbereg.h>
+#include <sgi/dev/mkbcreg.h>
+
#include <dev/cons.h>
#include <dev/ic/pckbcvar.h>
#include <dev/usb/ukbdvar.h>
#include <dev/wscons/wskbdvar.h>
#include <dev/wscons/wsconsio.h>
+#include "gbe.h"
#include "mkbc.h"
#include "wsdisplay.h"
@@ -73,12 +78,21 @@ wscnprobe(struct consdev *cp)
}
cp->cn_dev = makedev(maj, 0);
-
- /* Attach as console if necessary. */
- if (strncmp(bios_console, "video", 5) == 0) {
- cp->cn_pri = CN_REMOTE;
- } else {
- cp->cn_pri = CN_INTERNAL;
+ cp->cn_pri = CN_DEAD;
+
+ switch (sys_config.system_type) {
+ case SGI_O2:
+#if NGBE > 0
+ if (gbe_cnprobe(&crimebus_tag, GBE_BASE)) {
+ if (strncmp(bios_console, "video", 5) == 0)
+ cp->cn_pri = CN_FORCED;
+ else
+ cp->cn_pri = CN_INTERNAL;
+ }
+#endif
+ break;
+ default:
+ break;
}
}
@@ -92,15 +106,14 @@ static int initted;
initted = 1;
+#if NGBE > 0
+ if (!gbe_cnattach(&crimebus_tag, GBE_BASE))
+ return;
+#endif
#if NMKBC > 0
if (!mkbc_cnattach(&macebus_tag, 0x00320000, PCKBC_KBD_SLOT))
return;
#endif
-#if notyet
- ukbd_cnattach();
-#endif
-
- return;
}
void