summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2002-08-31 10:47:21 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2002-08-31 10:47:21 +0000
commit191f491511040cc900d4077c1859281bb34ac11d (patch)
tree3b4b08fccb2bccfdbb81e8e1022a4687569a9e30 /sys/arch
parentc2d35893bfb9957f59ce41e9cc1d27c7f08c81e8 (diff)
Driver for the Vigra VS10 and VS12 SBus framebuffers, and possibly more from
this series. Thanks to Andrey Smagin (andrey at smagin dot com) for providing a VS10 card.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/sparc/conf/GENERIC6
-rw-r--r--sys/arch/sparc/conf/RAMDISK6
-rw-r--r--sys/arch/sparc/conf/SUN4C4
-rw-r--r--sys/arch/sparc/conf/SUN4M6
-rw-r--r--sys/arch/sparc/conf/files.sparc6
-rw-r--r--sys/arch/sparc/dev/vigra.c520
6 files changed, 543 insertions, 5 deletions
diff --git a/sys/arch/sparc/conf/GENERIC b/sys/arch/sparc/conf/GENERIC
index 144990f3914..3c31a82c92b 100644
--- a/sys/arch/sparc/conf/GENERIC
+++ b/sys/arch/sparc/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.54 2002/08/21 22:18:29 miod Exp $
+# $OpenBSD: GENERIC,v 1.55 2002/08/31 10:47:18 miod Exp $
# $NetBSD: GENERIC,v 1.48 1997/08/23 19:19:01 mjacob Exp $
# Machine architecture; required by config(8)
@@ -268,6 +268,10 @@ wsdisplay* at cgfourteen?
cgtwelve* at sbus? slot ? offset ?
wsdisplay* at cgtwelve?
+# Vigra VS10 or VS12 framebuffer.
+vigra* at sbus? slot ? offset ?
+wsdisplay* at vigra?
+
# Weitek p9100 found on Tadpole 3GS/3GX
pnozz0 at sbus? slot ? offset ?
wsdisplay* at pnozz?
diff --git a/sys/arch/sparc/conf/RAMDISK b/sys/arch/sparc/conf/RAMDISK
index 902837ff00e..8127fbb3bcb 100644
--- a/sys/arch/sparc/conf/RAMDISK
+++ b/sys/arch/sparc/conf/RAMDISK
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISK,v 1.33 2002/08/30 09:31:33 miod Exp $
+# $OpenBSD: RAMDISK,v 1.34 2002/08/31 10:47:18 miod Exp $
# $NetBSD: GENERIC,v 1.28.2.1 1996/07/02 23:55:22 jtc Exp $
# Machine architecture; required by config(8)
@@ -262,6 +262,10 @@ wsdisplay* at cgfourteen?
cgtwelve* at sbus? slot ? offset ?
wsdisplay* at cgtwelve?
+# Vigra VS10 or VS12 framebuffer.
+vigra* at sbus? slot ? offset ?
+wsdisplay* at vigra?
+
# Weitek p9100 found on Tadpole 3GS/3GX
pnozz0 at sbus? slot ? offset ?
wsdisplay* at pnozz?
diff --git a/sys/arch/sparc/conf/SUN4C b/sys/arch/sparc/conf/SUN4C
index 212bd441713..707dd77a495 100644
--- a/sys/arch/sparc/conf/SUN4C
+++ b/sys/arch/sparc/conf/SUN4C
@@ -1,4 +1,4 @@
-# $OpenBSD: SUN4C,v 1.32 2002/08/12 10:44:03 miod Exp $
+# $OpenBSD: SUN4C,v 1.33 2002/08/31 10:47:18 miod Exp $
# $NetBSD: GENERIC,v 1.19 1995/10/08 11:45:39 pk Exp $
machine sparc
@@ -163,11 +163,13 @@ bwtwo* at sbus? slot ? offset ?
cgthree* at sbus? slot ? offset ?
cgsix* at sbus? slot ? offset ?
cgtwelve* at sbus? slot ? offset ?
+vigra* at sbus? slot ? offset ?
wsdisplay* at bwtwo?
wsdisplay* at cgthree?
wsdisplay* at cgsix?
wsdisplay* at cgtwelve?
+wsdisplay* at vigra?
scsibus* at esp?
#scsibus* at si?
diff --git a/sys/arch/sparc/conf/SUN4M b/sys/arch/sparc/conf/SUN4M
index f57155c11f9..b1743a953e3 100644
--- a/sys/arch/sparc/conf/SUN4M
+++ b/sys/arch/sparc/conf/SUN4M
@@ -1,4 +1,4 @@
-# $OpenBSD: SUN4M,v 1.42 2002/08/21 22:18:29 miod Exp $
+# $OpenBSD: SUN4M,v 1.43 2002/08/31 10:47:18 miod Exp $
# $NetBSD: GENERIC,v 1.28.2.1 1996/07/02 23:55:22 jtc Exp $
# Machine architecture; required by config(8)
@@ -152,6 +152,10 @@ wsdisplay* at cgfourteen?
cgtwelve* at sbus? slot ? offset ?
wsdisplay* at cgtwelve?
+# Vigra VS10 or VS12 framebuffer.
+vigra* at sbus? slot ? offset ?
+wsdisplay* at vigra?
+
# Weitek p9100 found on Tadpole 3GS/3GX
pnozz0 at sbus? slot ? offset ?
wsdisplay* at pnozz?
diff --git a/sys/arch/sparc/conf/files.sparc b/sys/arch/sparc/conf/files.sparc
index c7ad155000d..1b1819f08e9 100644
--- a/sys/arch/sparc/conf/files.sparc
+++ b/sys/arch/sparc/conf/files.sparc
@@ -1,4 +1,4 @@
-# $OpenBSD: files.sparc,v 1.43 2002/08/12 10:44:03 miod Exp $
+# $OpenBSD: files.sparc,v 1.44 2002/08/31 10:47:18 miod Exp $
# $NetBSD: files.sparc,v 1.44 1997/08/31 21:29:16 pk Exp $
# @(#)files.sparc 8.1 (Berkeley) 7/19/93
@@ -199,6 +199,10 @@ device tcx: wsemuldisplaydev, rasops8, rasops32, wsemul_sun, bt_dac
attach tcx at sbus
file arch/sparc/dev/tcx.c tcx
+device vigra: wsemuldisplaydev, rasops8, wsemul_sun
+attach vigra at sbus
+file arch/sparc/dev/vigra.c vigra
+
# device definition in sys/conf/files
attach le at sbus, ledma, lebuffer, obio
file arch/sparc/dev/if_le.c le
diff --git a/sys/arch/sparc/dev/vigra.c b/sys/arch/sparc/dev/vigra.c
new file mode 100644
index 00000000000..d96e6157003
--- /dev/null
+++ b/sys/arch/sparc/dev/vigra.c
@@ -0,0 +1,520 @@
+/* $OpenBSD: vigra.c,v 1.1 2002/08/31 10:47:20 miod Exp $ */
+
+/*
+ * Copyright (c) 2002 Miodrag Vallat. 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.
+ *
+ * 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.
+ *
+ */
+
+/*
+ * Driver for the Vigra VS series of SBus framebuffers.
+ *
+ * The VS10 and VS12 models are supported. VS10-EK should also work.
+ *
+ * The VS11 uses an INMOS G335 dac instead of the G300 found in VS10/12, and
+ * should be relatively easy to support once the dac diffs are sorted out.
+ *
+ * The monochrome VS14, 16 grays VS15, and color VS18 are not supported.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/device.h>
+#include <sys/ioctl.h>
+#include <sys/malloc.h>
+#include <sys/mman.h>
+#include <sys/tty.h>
+#include <sys/conf.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/autoconf.h>
+#include <machine/pmap.h>
+#include <machine/cpu.h>
+#include <machine/conf.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/wscons/wscons_raster.h>
+#include <dev/rasops/rasops.h>
+#include <machine/fbvar.h>
+
+#include <sparc/dev/sbusvar.h>
+
+/*
+ * INMOS G300 registers (very incomplete...)
+ */
+
+struct g300regs {
+ u_int32_t unknown00;
+ u_int32_t unknown04;
+ u_int32_t disable;
+ u_int32_t unknown0c;
+ u_int32_t status;
+#define G300S_INTR 0x0001
+ u_int32_t intr;
+ u_int32_t unknown18;
+ u_int32_t unknown1c;
+};
+
+/*
+ * SBUS register mappings
+ */
+#define VIGRA_REG_CMAP 1
+#define VIGRA_REG_G300 2
+#define VIGRA_REG_VRAM 3
+
+#define VIGRA_NREG 4
+
+union vigracmap {
+ u_char cm_map[256][4]; /* 256 R/G/B entries plus pad */
+ u_int32_t cm_chip[256]; /* the way the chip gets loaded */
+};
+
+/* per-display variables */
+struct vigra_softc {
+ struct sunfb sc_sunfb; /* common base part */
+ struct sbusdev sc_sd; /* sbus device */
+ struct rom_reg sc_phys; /* phys address description */
+ volatile struct g300regs *sc_regs; /* ramdac registers */
+ volatile u_int32_t *sc_physcmap; /* ramdac palette */
+ union vigracmap sc_cmap; /* current colormap */
+ struct intrhand sc_ih;
+ int sc_nscreens;
+};
+
+struct wsscreen_descr vigra_stdscreen = {
+ "std",
+ 0, 0, /* will be filled in */
+ 0,
+ 0, 0,
+ WSSCREEN_REVERSE | WSSCREEN_WSCOLORS
+};
+
+const struct wsscreen_descr *vigra_scrlist[] = {
+ &vigra_stdscreen,
+};
+
+struct wsscreen_list vigra_screenlist = {
+ sizeof(vigra_scrlist) / sizeof(struct wsscreen_descr *),
+ vigra_scrlist
+};
+
+int vigra_ioctl(void *, u_long, caddr_t, int, struct proc *);
+int vigra_alloc_screen(void *, const struct wsscreen_descr *, void **,
+ int *, int *, long *);
+void vigra_free_screen(void *, void *);
+int vigra_show_screen(void *, void *, int, void (*cb)(void *, int, int),
+ void *);
+paddr_t vigra_mmap(void *, off_t, int);
+void vigra_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
+int vigra_getcmap(union vigracmap *, struct wsdisplay_cmap *);
+int vigra_putcmap(union vigracmap *, struct wsdisplay_cmap *);
+void vigra_loadcmap_immediate(struct vigra_softc *, int, int);
+static __inline__ void vigra_loadcmap_deferred(struct vigra_softc *,
+ u_int, u_int);
+void vigra_burner(void *, u_int, u_int);
+int vigra_intr(void *);
+
+struct wsdisplay_accessops vigra_accessops = {
+ vigra_ioctl,
+ vigra_mmap,
+ vigra_alloc_screen,
+ vigra_free_screen,
+ vigra_show_screen,
+ NULL, /* load_font */
+ NULL, /* scrollback */
+ NULL, /* getchar */
+ vigra_burner,
+};
+
+int vigramatch(struct device *, void *, void *);
+void vigraattach(struct device *, struct device *, void *);
+
+struct cfattach vigra_ca = {
+ sizeof (struct vigra_softc), vigramatch, vigraattach
+};
+
+struct cfdriver vigra_cd = {
+ NULL, "vigra", DV_DULL
+};
+
+/*
+ * Match a vigra.
+ */
+int
+vigramatch(parent, vcf, aux)
+ struct device *parent;
+ void *vcf, *aux;
+{
+ struct cfdata *cf = vcf;
+ struct confargs *ca = aux;
+ struct romaux *ra = &ca->ca_ra;
+
+ /*
+ * Mask out invalid flags from the user.
+ */
+ cf->cf_flags &= FB_USERMASK;
+
+ if (strcmp("vs10", ra->ra_name) && strcmp("vs12", ra->ra_name))
+ return (0);
+
+ if (ca->ca_bustype != BUS_SBUS)
+ return (0);
+
+ return (1);
+}
+
+/*
+ * Attach a display.
+ */
+void
+vigraattach(parent, self, args)
+ struct device *parent, *self;
+ void *args;
+{
+ struct vigra_softc *sc = (struct vigra_softc *)self;
+ struct confargs *ca = args;
+ struct wsemuldisplaydev_attach_args waa;
+ int node, row, isconsole = 0;
+ char *nam;
+
+ sc->sc_sunfb.sf_flags = self->dv_cfdata->cf_flags;
+
+ node = ca->ca_ra.ra_node;
+ nam = getpropstring(node, "model");
+ if (*nam == '\0')
+ nam = (char *)ca->ca_ra.ra_name;
+ printf(": %s", nam);
+
+ isconsole = node == fbnode;
+
+ if (ca->ca_ra.ra_nreg < VIGRA_NREG)
+ panic("\nexpected %d registers, got %d",
+ VIGRA_NREG, ca->ca_ra.ra_nreg);
+
+ sc->sc_regs = mapiodev(&ca->ca_ra.ra_reg[VIGRA_REG_G300], 0,
+ sizeof(*sc->sc_regs));
+ sc->sc_physcmap = mapiodev(&ca->ca_ra.ra_reg[VIGRA_REG_CMAP], 0,
+ 256 * sizeof(u_int32_t));
+ sc->sc_phys = ca->ca_ra.ra_reg[VIGRA_REG_VRAM];
+
+ sc->sc_ih.ih_fun = vigra_intr;
+ sc->sc_ih.ih_arg = sc;
+ intr_establish(ca->ca_ra.ra_intr[0].int_pri, &sc->sc_ih, IPL_FB);
+
+ /* enable video */
+ vigra_burner(sc, 1, 0);
+
+ fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype);
+ sc->sc_sunfb.sf_ro.ri_bits = mapiodev(&ca->ca_ra.ra_reg[VIGRA_REG_VRAM],
+ 0, round_page(sc->sc_sunfb.sf_fbsize));
+ sc->sc_sunfb.sf_ro.ri_hw = sc;
+
+ printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
+
+ /*
+ * If the framebuffer width is under 1024x768, we will switch from the
+ * PROM font to the more adequate 8x16 font here.
+ * However, we need to adjust two things in this case:
+ * - the display row should be overrided from the current PROM metrics,
+ * to prevent us from overwriting the last few lines of text.
+ * - if the 80x34 screen would make a large margin appear around it,
+ * choose to clear the screen rather than keeping old prom output in
+ * the margins.
+ * XXX there should be a rasops "clear margins" feature
+ */
+ fbwscons_init(&sc->sc_sunfb,
+ isconsole && (sc->sc_sunfb.sf_width != 800));
+
+ vigra_stdscreen.nrows = sc->sc_sunfb.sf_ro.ri_rows;
+ vigra_stdscreen.ncols = sc->sc_sunfb.sf_ro.ri_cols;
+ vigra_stdscreen.textops = &sc->sc_sunfb.sf_ro.ri_ops;
+
+ if (isconsole) {
+ switch (sc->sc_sunfb.sf_width) {
+ case 640:
+ row = vigra_stdscreen.nrows - 1;
+ break;
+ case 800:
+ row = 0; /* screen has been cleared above */
+ break;
+ default:
+ row = -1;
+ break;
+ }
+
+ fbwscons_console_init(&sc->sc_sunfb, &vigra_stdscreen, row,
+ vigra_setcolor, vigra_burner);
+ }
+
+ sbus_establish(&sc->sc_sd, &sc->sc_sunfb.sf_dev);
+
+ waa.console = isconsole;
+ waa.scrdata = &vigra_screenlist;
+ waa.accessops = &vigra_accessops;
+ waa.accesscookie = sc;
+ config_found(self, &waa, wsemuldisplaydevprint);
+}
+
+int
+vigra_ioctl(v, cmd, data, flags, p)
+ void *v;
+ u_long cmd;
+ caddr_t data;
+ int flags;
+ struct proc *p;
+{
+ struct vigra_softc *sc = v;
+ struct wsdisplay_cmap *cm;
+ struct wsdisplay_fbinfo *wdf;
+ int error;
+
+ switch (cmd) {
+ case WSDISPLAYIO_GTYPE:
+ *(u_int *)data = WSDISPLAY_TYPE_UNKNOWN;
+ break;
+ case WSDISPLAYIO_GINFO:
+ wdf = (struct wsdisplay_fbinfo *)data;
+ wdf->height = sc->sc_sunfb.sf_height;
+ wdf->width = sc->sc_sunfb.sf_width;
+ wdf->depth = sc->sc_sunfb.sf_depth;
+ wdf->cmsize = 256;
+ break;
+ case WSDISPLAYIO_LINEBYTES:
+ *(u_int *)data = sc->sc_sunfb.sf_linebytes;
+ break;
+
+ case WSDISPLAYIO_GETCMAP:
+ cm = (struct wsdisplay_cmap *)data;
+ error = vigra_getcmap(&sc->sc_cmap, cm);
+ if (error)
+ return (error);
+ break;
+ case WSDISPLAYIO_PUTCMAP:
+ cm = (struct wsdisplay_cmap *)data;
+ error = vigra_putcmap(&sc->sc_cmap, cm);
+ if (error)
+ return (error);
+ vigra_loadcmap_deferred(sc, cm->index, cm->count);
+ break;
+
+ case WSDISPLAYIO_SVIDEO:
+ case WSDISPLAYIO_GVIDEO:
+ case WSDISPLAYIO_GCURPOS:
+ case WSDISPLAYIO_SCURPOS:
+ case WSDISPLAYIO_GCURMAX:
+ case WSDISPLAYIO_GCURSOR:
+ case WSDISPLAYIO_SCURSOR:
+ default:
+ return (-1); /* not supported yet */
+ }
+
+ return (0);
+}
+
+int
+vigra_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
+ void *v;
+ const struct wsscreen_descr *type;
+ void **cookiep;
+ int *curxp, *curyp;
+ long *attrp;
+{
+ struct vigra_softc *sc = v;
+
+ if (sc->sc_nscreens > 0)
+ return (ENOMEM);
+
+ *cookiep = &sc->sc_sunfb.sf_ro;
+ *curyp = 0;
+ *curxp = 0;
+ sc->sc_sunfb.sf_ro.ri_ops.alloc_attr(&sc->sc_sunfb.sf_ro,
+ WSCOL_BLACK, WSCOL_WHITE, WSATTR_WSCOLORS, attrp);
+ sc->sc_nscreens++;
+ return (0);
+}
+
+void
+vigra_free_screen(v, cookie)
+ void *v;
+ void *cookie;
+{
+ struct vigra_softc *sc = v;
+
+ sc->sc_nscreens--;
+}
+
+int
+vigra_show_screen(v, cookie, waitok, cb, cbarg)
+ void *v;
+ void *cookie;
+ int waitok;
+ void (*cb)(void *, int, int);
+ void *cbarg;
+{
+ return (0);
+}
+
+/*
+ * Return the address that would map the given device at the given
+ * offset, allowing for the given protection, or return -1 for error.
+ */
+paddr_t
+vigra_mmap(v, offset, prot)
+ void *v;
+ off_t offset;
+ int prot;
+{
+ struct vigra_softc *sc = v;
+
+ if (offset & PGOFSET)
+ return (-1);
+
+ if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize) {
+ return (REG2PHYS(&sc->sc_phys, offset) | PMAP_NC);
+ }
+
+ return (-1);
+}
+
+void
+vigra_setcolor(v, index, r, g, b)
+ void *v;
+ u_int index;
+ u_int8_t r, g, b;
+{
+ struct vigra_softc *sc = v;
+
+ sc->sc_cmap.cm_map[index][3] = r;
+ sc->sc_cmap.cm_map[index][2] = g;
+ sc->sc_cmap.cm_map[index][1] = b;
+ sc->sc_cmap.cm_map[index][0] = 0; /* no alpha channel */
+
+ vigra_loadcmap_immediate(sc, index, 1);
+}
+
+int
+vigra_getcmap(cm, rcm)
+ union vigracmap *cm;
+ struct wsdisplay_cmap *rcm;
+{
+ u_int index = rcm->index, count = rcm->count, i;
+ int error;
+
+ if (index >= 256 || count > 256 - index)
+ return (EINVAL);
+
+ for (i = 0; i < count; i++) {
+ if ((error = copyout(&cm->cm_map[index + i][3],
+ &rcm->red[i], 1)) != 0)
+ return (error);
+ if ((error = copyout(&cm->cm_map[index + i][2],
+ &rcm->green[i], 1)) != 0)
+ return (error);
+ if ((error = copyout(&cm->cm_map[index + i][1],
+ &rcm->blue[i], 1)) != 0)
+ return (error);
+ }
+ return (0);
+}
+
+int
+vigra_putcmap(cm, rcm)
+ union vigracmap *cm;
+ struct wsdisplay_cmap *rcm;
+{
+ u_int index = rcm->index, count = rcm->count, i;
+ int error;
+
+ if (index >= 256 || count > 256 - index)
+ return (EINVAL);
+
+ for (i = 0; i < count; i++) {
+ if ((error = copyin(&rcm->red[i],
+ &cm->cm_map[index + i][3], 1)) != 0)
+ return (error);
+ if ((error = copyin(&rcm->green[i],
+ &cm->cm_map[index + i][2], 1)) != 0)
+ return (error);
+ if ((error = copyin(&rcm->blue[i],
+ &cm->cm_map[index + i][1], 1)) != 0)
+ return (error);
+ cm->cm_map[index + i][0] = 0; /* no alpha channel */
+ }
+ return (0);
+}
+
+void
+vigra_loadcmap_immediate(sc, start, ncolors)
+ struct vigra_softc *sc;
+ int start, ncolors;
+{
+ u_int32_t *colp = &sc->sc_cmap.cm_chip[start];
+ volatile u_int32_t *lutp = &sc->sc_physcmap[start];
+
+ while (--ncolors >= 0)
+ *lutp++ = *colp++;
+}
+
+static __inline__ void
+vigra_loadcmap_deferred(struct vigra_softc *sc, u_int start, u_int ncolors)
+{
+
+ sc->sc_regs->intr = 1;
+}
+
+void
+vigra_burner(v, on, flags)
+ void *v;
+ u_int on, flags;
+{
+ struct vigra_softc *sc = v;
+
+ if (on) {
+ sc->sc_regs->disable = 0;
+ } else {
+ sc->sc_regs->disable = 1;
+ }
+}
+
+int
+vigra_intr(v)
+ void *v;
+{
+ struct vigra_softc *sc = v;
+
+ if (sc->sc_regs->intr == 0 ||
+ !ISSET(sc->sc_regs->status, G300S_INTR)) {
+ /* Not expecting an interrupt, it's not for us. */
+ return (0);
+ }
+
+ /* Acknowledge the interrupt and disable it. */
+ sc->sc_regs->intr = 0;
+
+ vigra_loadcmap_immediate(sc, 0, 256);
+
+ return (1);
+}