Checkpoint the GR2 wscons driver. Heavily derived from lonewolf@'s newport

driver.  Still some issues:

* framebuffer setup seems incomplete.  Some drawing primitives work 100%
  of the time, while others fail one in ten tries.  Perhaps my board is
  slightly broken, as the exact model as probed by ARCS seems to shift
  between Elan and XS24 from time to time.
* characters are drawn bottom-up rather than top-down (as the wsfont
  definitions expect).
This commit is contained in:
sekiya 2004-03-18 08:52:04 +00:00
parent 0ee588cc1c
commit 27be14d39c

View File

@ -0,0 +1,725 @@
/* $NetBSD: grtwo.c,v 1.1 2004/03/18 08:52:04 sekiya Exp $ */
/*
* Copyright (c) 2004 Christopher SEKIYA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>>
*/
/* wscons driver for SGI GR2 family of framebuffers
*
* Heavily based on the newport wscons driver.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: grtwo.c,v 1.1 2004/03/18 08:52:04 sekiya Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/malloc.h>
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsdisplayvar.h>
#include <dev/wsfont/wsfont.h>
#include <sgimips/gio/giovar.h>
#include <sgimips/gio/grtwovar.h>
#include <sgimips/gio/grtworeg.h>
#include <sgimips/dev/int2var.h>
struct grtwo_softc {
struct device sc_dev;
struct grtwo_devconfig *sc_dc;
};
struct grtwo_devconfig {
u_int32_t dc_addr;
bus_space_tag_t iot;
bus_space_handle_t ioh;
u_int8_t boardrev;
u_int8_t backendrev;
int hq2rev;
int ge7rev;
int vc1rev;
int zbuffer;
int cmaprev;
int xmaprev;
int rexrev;
int xres;
int yres;
int depth;
int monitor;
int dc_font;
struct wsdisplay_font *dc_fontdata;
};
static int grtwo_match(struct device *, struct cfdata *, void *);
static void grtwo_attach(struct device *, struct device *, void *);
CFATTACH_DECL(grtwo, sizeof(struct grtwo_softc),
grtwo_match, grtwo_attach, NULL, NULL);
/* textops */
static void grtwo_cursor(void *, int, int, int);
static int grtwo_mapchar(void *, int, unsigned int *);
static void grtwo_putchar(void *, int, int, u_int, long);
static void grtwo_copycols(void *, int, int, int, int);
static void grtwo_erasecols(void *, int, int, int, long);
static void grtwo_copyrows(void *, int, int, int);
static void grtwo_eraserows(void *, int, int, long);
static int grtwo_allocattr(void *, int, int, int, long *);
/* accessops */
static int grtwo_ioctl(void *, u_long, caddr_t, int, struct proc *);
static paddr_t grtwo_mmap(void *, off_t, int);
static int
grtwo_alloc_screen(void *, const struct wsscreen_descr *,
void **, int *, int *, long *);
static void grtwo_free_screen(void *, void *);
static int
grtwo_show_screen(void *, void *, int, void (*) (void *, int, int), void *);
static const struct wsdisplay_emulops grtwo_textops = {
.cursor = grtwo_cursor,
.mapchar = grtwo_mapchar,
.putchar = grtwo_putchar,
.copycols = grtwo_copycols,
.erasecols = grtwo_erasecols,
.copyrows = grtwo_copyrows,
.eraserows = grtwo_eraserows,
.allocattr = grtwo_allocattr
};
static const struct wsdisplay_accessops grtwo_accessops = {
.ioctl = grtwo_ioctl,
.mmap = grtwo_mmap,
.alloc_screen = grtwo_alloc_screen,
.free_screen = grtwo_free_screen,
.show_screen = grtwo_show_screen,
};
static const struct wsscreen_descr grtwo_screen = {
.name = "1280x1024",
.ncols = 160,
.nrows = 64,
.textops = &grtwo_textops,
.fontwidth = 8,
.fontheight = 16,
.capabilities = WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_REVERSE
};
static const struct wsscreen_descr *_grtwo_screenlist[] = {
&grtwo_screen
};
static const struct wsscreen_list grtwo_screenlist = {
sizeof(_grtwo_screenlist) / sizeof(struct wsscreen_descr *),
_grtwo_screenlist
};
static struct grtwo_devconfig grtwo_console_dc;
static int grtwo_is_console = 0;
#define GR2_ATTR_ENCODE(fg,bg) (((fg) << 8) | (bg))
#define GR2_ATTR_BG(a) ((a) & 0xff)
#define GR2_ATTR_FG(a) (((a) >> 8) & 0xff)
static const u_int16_t grtwo_cursor_data[128] = {
/* Bit 0 */
0xff00, 0x0000,
0xff00, 0x0000,
0xff00, 0x0000,
0xff00, 0x0000,
0xff00, 0x0000,
0xff00, 0x0000,
0xff00, 0x0000,
0xff00, 0x0000,
0xff00, 0x0000,
0xff00, 0x0000,
0xff00, 0x0000,
0xff00, 0x0000,
0xff00, 0x0000,
0xff00, 0x0000,
0xff00, 0x0000,
0xff00, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
/* Bit 1 */
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
};
static const u_int8_t grtwo_defcmap[8 * 3] = {
/* Normal colors */
0x00, 0x00, 0x00, /* black */
0x7f, 0x00, 0x00, /* red */
0x00, 0x7f, 0x00, /* green */
0x7f, 0x7f, 0x00, /* brown */
0x00, 0x00, 0x7f, /* blue */
0x7f, 0x00, 0x7f, /* magenta */
0x00, 0x7f, 0x7f, /* cyan */
0xc7, 0xc7, 0xc7, /* white - XXX too dim? */
};
static void
grtwo_wait_gfifo(struct grtwo_devconfig * dc)
{
int2_wait_fifo(1);
}
/* Helper functions */
static void
grtwo_fill_rectangle(struct grtwo_devconfig * dc, int x1, int y1, int x2,
int y2, u_int8_t color)
{
/* gr2 sees coordinate 0,0 as the lower left corner of the screen */
y1 = dc->yres - y1;
y2 = dc->yres - y2;
grtwo_wait_gfifo(dc);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_COLOR, color);
grtwo_wait_gfifo(dc);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_RECTI2D, x1);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, y1);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, x2);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, y2);
}
static void
grtwo_copy_rectangle(struct grtwo_devconfig * dc, int x1, int y1, int x2,
int y2, int dx, int dy)
{
int length = (dx + 3) >> 2;
int lines = 4864 / length;
int from_y;
int to_y;
int height;
y1 = dc->yres - y1 - dy;
y2 = dc->yres - y2 - dy;
if ((y2 <= y1) || (dy < lines)) {
grtwo_wait_gfifo(dc);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_RECTCOPY, length);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, lines);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, x1);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, y1);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, dx);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, dy);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, x2);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, y2);
} else {
from_y = y1 + dy - lines;
to_y = y2 + dy - lines;
height = MIN(dy, lines);
while (height) {
grtwo_wait_gfifo(dc);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_RECTCOPY, length);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, lines);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, x1);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, from_y);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, dx);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, height);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, x2);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, to_y);
dy -= height;
height = MIN(dy, lines);
from_y -= height;
to_y -= height;
}
}
}
static void
grtwo_cmap_setrgb(struct grtwo_devconfig * dc, int index, u_int8_t r, u_int8_t g, u_int8_t b)
{
/* index += 0x1000; */
grtwo_wait_gfifo(dc);
bus_space_write_4(dc->iot, dc->ioh, XMAPALL_ADDRHI,
(index & 0x1f00) >> 8);
bus_space_write_4(dc->iot, dc->ioh, XMAPALL_ADDRLO,
(index & 0xff));
bus_space_write_4(dc->iot, dc->ioh, XMAPALL_CLUT, r);
bus_space_write_4(dc->iot, dc->ioh, XMAPALL_CLUT, g);
bus_space_write_4(dc->iot, dc->ioh, XMAPALL_CLUT, b);
}
static void
grtwo_setup_hw(struct grtwo_devconfig * dc)
{
int i = 0;
/* Get various revisions */
dc->boardrev = (~(bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD0))) & GR2_REVISION_RD0_VERSION_MASK;
/*
* boards prior to rev 4 have a pretty whacky config scheme.
* what is doubly weird is that i have a rev 2 board, but the rev 4
* probe routines work just fine.
* we'll trust SGI, though, and separate things a bit. it's only
* critical for the display depth calculation.
*/
if (dc->boardrev < 4) {
dc->backendrev = ~(bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD2) & GR2_REVISION_RD2_BACKEND_REV) >> 2;
if (dc->backendrev == 0)
return;
dc->zbuffer = !(bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD1) & GR2_REVISION_RD1_ZBUFFER);
if ( (bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD3) & GR2_REVISION_RD3_VMA) != 3)
i++;
if ( (bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD3) & GR2_REVISION_RD3_VMB) != 0x0c)
i++;
if ( (bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD3) & GR2_REVISION_RD3_VMC) != 0x30)
i++;
dc->depth = 8 * i;
dc->monitor =
((bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD2) & 0x03) << 1) |
(bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD1) & 0x01);
} else {
dc->backendrev = ~(bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD1)) & 0x03;
if (dc->backendrev == 0)
return;
dc->zbuffer = bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD1) & GR2_REVISION4_RD1_ZBUFFER;
dc->depth = ((bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD1) & GR2_REVISION4_RD1_24BPP) >> 4) ? 24 : 8;
dc->monitor = (bus_space_read_4(dc->iot, dc->ioh, GR2_REVISION_RD0) & GR2_REVISION4_RD0_MONITOR_MASK) >> 4;
}
dc->hq2rev = (bus_space_read_4(dc->iot, dc->ioh, HQ2_VERSION) & HQ2_VERSION_MASK) >> HQ2_VERSION_SHIFT;
dc->ge7rev = (bus_space_read_4(dc->iot, dc->ioh, GE7_REVISION) & GE7_REVISION_MASK) >> 5;
/* dc->vc1rev = vc1_read_ireg(dc, 5) & 0x07; */
/* gr2 supports 1280x1024 only */
dc->xres = 1280;
dc->yres = 1024;
#if 0
/* Setup cursor glyph */
bus_space_write_4(dc->iot, dc->ioh, VC1_ADDRHI,
(VC1_SRAM_CURSOR0_BASE >> 8) & 0xff);
bus_space_write_4(dc->iot, dc->ioh, VC1_ADDRLO,
VC1_SRAM_CURSOR0_BASE & 0xff);
for (i = 0; i < 128; i++)
bus_space_write_4(dc->iot, dc->ioh, VC1_SRAM, grtwo_cursor_data[i]);
bus_space_write_4(dc->iot, dc->ioh, VC1_ADDRHI,
(VC1_CURSOR_EP >> 8) & 0xff);
bus_space_write_4(dc->iot, dc->ioh, VC1_ADDRLO,
VC1_CURSOR_EP & 0xff);
bus_space_write_4(dc->iot, dc->ioh, VC1_COMMAND, VC1_SRAM_CURSOR0_BASE);
bus_space_write_4(dc->iot, dc->ioh, VC1_COMMAND, 0);
bus_space_write_4(dc->iot, dc->ioh, VC1_COMMAND, 0);
bus_space_write_4(dc->iot, dc->ioh, VC1_COMMAND, 0);
/* Turn on cursor function, display, DID */
bus_space_write_4(dc->iot, dc->ioh, VC1_SYSCTL,
VC1_SYSCTL_VC1 | VC1_SYSCTL_DID |
VC1_SYSCTL_CURSOR | VC1_SYSCTL_CURSOR_DISPLAY);
#endif
/* Setup CMAP */
for (i = 0; i < 8; i++)
grtwo_cmap_setrgb(dc, i, grtwo_defcmap[i * 3],
grtwo_defcmap[i * 3 + 1], grtwo_defcmap[i * 3 + 2]);
}
/* Attach routines */
static int
grtwo_match(struct device * parent, struct cfdata * self, void *aux)
{
struct gio_attach_args *ga = aux;
/*
* grtwo doesn't have anything that even vaguely resembles a product
* ID. Instead, we determine presence by looking at the HQ2 "mystery"
* register, which contains a magic number.
*/
if ( badaddr((void *) (ga->ga_ioh + HQ2_MYSTERY), sizeof(u_int32_t)) )
return 0;
if ( (bus_space_read_4(ga->ga_iot, ga->ga_ioh, HQ2_MYSTERY)) != 0xdeadbeef)
return 0;
return 1;
}
static void
grtwo_attach_common(struct grtwo_devconfig * dc, struct gio_attach_args * ga)
{
dc->dc_addr = ga->ga_addr;
dc->iot = ga->ga_iot;
dc->ioh = ga->ga_ioh;
wsfont_init();
dc->dc_font = wsfont_find(NULL, 8, 16, 0, WSDISPLAY_FONTORDER_L2R,
WSDISPLAY_FONTORDER_L2R);
if (dc->dc_font < 0)
panic("grtwo_attach_common: no suitable fonts");
if (wsfont_lock(dc->dc_font, &dc->dc_fontdata))
panic("grtwo_attach_common: unable to lock font data");
grtwo_setup_hw(dc);
grtwo_fill_rectangle(dc, 0, 0, dc->xres, dc->yres, 0);
}
static void
grtwo_attach(struct device * parent, struct device * self, void *aux)
{
struct gio_attach_args *ga = aux;
struct grtwo_softc *sc = (void *) self;
struct wsemuldisplaydev_attach_args wa;
if (grtwo_is_console && ga->ga_addr == grtwo_console_dc.dc_addr) {
wa.console = 1;
sc->sc_dc = &grtwo_console_dc;
} else {
wa.console = 0;
sc->sc_dc = malloc(sizeof(struct grtwo_devconfig),
M_DEVBUF, M_WAITOK | M_ZERO);
if (sc->sc_dc == NULL)
panic("grtwo_attach: out of memory");
grtwo_attach_common(sc->sc_dc, ga);
}
aprint_naive(": Display adapter\n");
aprint_normal(": SGI GR2 (board rev %x, monitor %d, depth %d)\n",
sc->sc_dc->boardrev, sc->sc_dc->monitor, sc->sc_dc->depth);
wa.scrdata = &grtwo_screenlist;
wa.accessops = &grtwo_accessops;
wa.accesscookie = sc->sc_dc;
config_found(&sc->sc_dev, &wa, wsemuldisplaydevprint);
}
int
grtwo_cnattach(struct gio_attach_args * ga)
{
long defattr = GR2_ATTR_ENCODE(WSCOL_WHITE, WSCOL_BLACK);
const struct wsscreen_descr *screen;
if (!grtwo_match(NULL, NULL, ga)) {
return ENXIO;
}
grtwo_attach_common(&grtwo_console_dc, ga);
screen = &grtwo_screen;
wsdisplay_cnattach(screen, &grtwo_console_dc, 0, 0, defattr);
grtwo_is_console = 1;
return 0;
}
/* wsdisplay textops */
static void
grtwo_cursor(void *c, int on, int row, int col)
{
struct grtwo_devconfig *dc = (void *) c;
u_int32_t control;
control = bus_space_read_4(dc->iot, dc->ioh, VC1_SYSCTL);
if (!on) {
bus_space_write_4(dc->iot, dc->ioh, VC1_SYSCTL,
control & ~VC1_SYSCTL_CURSOR_DISPLAY);
} else {
bus_space_write_4(dc->iot, dc->ioh, VC1_ADDRHI, (VC1_CURSOR_XL & 0xff00) >> 8
);
bus_space_write_4(dc->iot, dc->ioh, VC1_ADDRLO, VC1_CURSOR_XL & 0xff);
bus_space_write_4(dc->iot, dc->ioh, VC1_COMMAND,
col * dc->dc_fontdata->fontwidth);
bus_space_write_4(dc->iot, dc->ioh, VC1_COMMAND,
row * dc->dc_fontdata->fontheight);
bus_space_write_4(dc->iot, dc->ioh, VC1_SYSCTL,
control | VC1_SYSCTL_CURSOR_DISPLAY);
}
}
static int
grtwo_mapchar(void *c, int ch, unsigned int *cp)
{
struct grtwo_devconfig *dc = (void *) c;
if (dc->dc_fontdata->encoding != WSDISPLAY_FONTENC_ISO) {
ch = wsfont_map_unichar(dc->dc_fontdata, ch);
if (ch < 0)
goto fail;
}
if (ch < dc->dc_fontdata->firstchar ||
ch >= dc->dc_fontdata->firstchar + dc->dc_fontdata->numchars)
goto fail;
*cp = ch;
return 5;
fail:
*cp = ' ';
return 0;
}
static void
grtwo_putchar(void *c, int row, int col, u_int ch, long attr)
{
struct grtwo_devconfig *dc = (void *) c;
struct wsdisplay_font *font = dc->dc_fontdata;
u_int8_t *bitmap = (u_int8_t *) font->data + (ch - font->firstchar) * font->fontheight * font->stride;
u_int32_t pattern;
int i;
int x = col * font->fontwidth;
int y = dc->yres - ( (row + 1) * font->fontheight);
/* Set the drawing color */
grtwo_wait_gfifo(dc);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_COLOR, attr);
/* Set drawing coordinates */
grtwo_wait_gfifo(dc);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_CMOV2I, x);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, y);
grtwo_wait_gfifo(dc);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DRAWCHAR, font->fontwidth);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, font->fontheight);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, 1);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, 0); /* x offset */
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, 0); /* y offset */
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, 0);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, 0);
for (i = 0; i < font->fontheight; i++) {
/* It appears that writes have to be 16 bits. An "I tell you
two times" sort of thing? Thanks, SGI */
pattern = *bitmap | (*bitmap << 8);
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, pattern);
bitmap += font->stride;
}
/* pad up to 18 */
for (i = font->fontheight; i < 18; i++)
bus_space_write_4(dc->iot, dc->ioh, GR2_FIFO_DATA, 0x0000);
}
static void
grtwo_copycols(void *c, int row, int srccol, int dstcol, int ncols)
{
struct grtwo_devconfig *dc = (void *) c;
struct wsdisplay_font *font = dc->dc_fontdata;
grtwo_copy_rectangle(dc,
srccol * font->fontwidth, /* x1 */
row * font->fontheight, /* y1 */
(srccol + ncols + 1) * font->fontwidth - 1, /* x2 */
(row + 1) * font->fontheight - 1, /* y2 */
dstcol * font->fontheight, /* dx */
row * font->fontheight); /* dy */
}
static void
grtwo_erasecols(void *c, int row, int startcol, int ncols, long attr)
{
struct grtwo_devconfig *dc = (void *) c;
struct wsdisplay_font *font = dc->dc_fontdata;
grtwo_fill_rectangle(dc,
startcol * font->fontwidth, /* x1 */
row * font->fontheight, /* y1 */
(startcol + ncols + 1) * font->fontwidth - 1, /* x2 */
(row + 1) * font->fontheight - 1, /* y2 */
GR2_ATTR_BG(attr));
}
static void
grtwo_copyrows(void *c, int srcrow, int dstrow, int nrows)
{
struct grtwo_devconfig *dc = (void *) c;
struct wsdisplay_font *font = dc->dc_fontdata;
grtwo_copy_rectangle(dc,
0, /* x1 */
srcrow * font->fontheight, /* y1 */
dc->xres, /* x2 */
(srcrow + nrows + 1) * font->fontheight - 1, /* y2 */
0, /* dx */
dstrow * font->fontheight); /* dy */
}
static void
grtwo_eraserows(void *c, int startrow, int nrows, long attr)
{
struct grtwo_devconfig *dc = (void *) c;
struct wsdisplay_font *font = dc->dc_fontdata;
grtwo_fill_rectangle(dc,
0, /* x1 */
startrow * font->fontheight, /* y1 */
dc->xres, /* x2 */
(startrow + nrows + 1) * font->fontheight - 1, /* y2 */
GR2_ATTR_BG(attr));
}
static int
grtwo_allocattr(void *c, int fg, int bg, int flags, long *attr)
{
if (flags & WSATTR_BLINK)
return EINVAL;
if ((flags & WSATTR_WSCOLORS) == 0) {
fg = WSCOL_WHITE;
bg = WSCOL_BLACK;
}
if (flags & WSATTR_HILIT)
fg += 8;
if (flags & WSATTR_REVERSE) {
int tmp = fg;
fg = bg;
bg = tmp;
}
*attr = GR2_ATTR_ENCODE(fg, bg);
return 0;
}
/* wsdisplay accessops */
static int
grtwo_ioctl(void *c, u_long cmd, caddr_t data, int flag, struct proc * p)
{
struct grtwo_softc *sc = c;
#define FBINFO (*(struct wsdisplay_fbinfo*)data)
switch (cmd) {
case WSDISPLAYIO_GINFO:
FBINFO.width = sc->sc_dc->xres;
FBINFO.height = sc->sc_dc->yres;
FBINFO.depth = sc->sc_dc->depth;
FBINFO.cmsize = 1 << FBINFO.depth;
return 0;
case WSDISPLAYIO_GTYPE:
*(u_int *) data = WSDISPLAY_TYPE_GR2;
return 0;
}
return EPASSTHROUGH;
}
static paddr_t
grtwo_mmap(void *c, off_t offset, int prot)
{
struct grtwo_devconfig *dc = c;
if (offset >= 0xfffff)
return -1;
return mips_btop(dc->dc_addr + offset);
}
static int
grtwo_alloc_screen(void *c, const struct wsscreen_descr * type, void **cookiep,
int *cursxp, int *cursyp, long *attrp)
{
/*
* This won't get called for console screen and we don't support
* virtual screens
*/
return ENOMEM;
}
static void
grtwo_free_screen(void *c, void *cookie)
{
panic("grtwo_free_screen");
}
static int
grtwo_show_screen(void *c, void *cookie, int waitok,
void (*cb) (void *, int, int), void *cbarg)
{
return 0;
}