summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/sbus/cgsix.c58
1 files changed, 52 insertions, 6 deletions
diff --git a/sys/dev/sbus/cgsix.c b/sys/dev/sbus/cgsix.c
index cd79b118bc5..cb6acb3c8d3 100644
--- a/sys/dev/sbus/cgsix.c
+++ b/sys/dev/sbus/cgsix.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cgsix.c,v 1.14 2002/03/04 23:32:52 jason Exp $ */
+/* $OpenBSD: cgsix.c,v 1.15 2002/03/14 01:14:22 jason Exp $ */
/*
* Copyright (c) 2001 Jason L. Wright (jason@thought.net)
@@ -150,6 +150,7 @@ struct cgsix_softc {
struct rcons sc_rcons;
struct raster sc_raster;
union bt_cmap sc_cmap;
+ void *sc_ih;
};
#define CG6_USER_FBC 0x70000000
@@ -228,12 +229,14 @@ paddr_t cgsix_mmap __P((void *, off_t, int));
int cgsix_is_console __P((int));
int cg6_bt_getcmap __P((union bt_cmap *, struct wsdisplay_cmap *));
int cg6_bt_putcmap __P((union bt_cmap *, struct wsdisplay_cmap *));
-void cgsix_loadcmap __P((struct cgsix_softc *, u_int, u_int));
+void cgsix_loadcmap_immediate __P((struct cgsix_softc *, u_int, u_int));
+void cgsix_loadcmap_deferred __P((struct cgsix_softc *, u_int, u_int));
void cgsix_setcolor __P((struct cgsix_softc *, u_int,
u_int8_t, u_int8_t, u_int8_t));
void cgsix_reset __P((struct cgsix_softc *));
void cgsix_hardreset __P((struct cgsix_softc *));
void cgsix_burner __P((void *, u_int, u_int));
+int cgsix_intr __P((void *));
static int a2int __P((char *, int));
struct wsdisplay_accessops cgsix_accessops = {
@@ -327,6 +330,12 @@ cgsixattach(parent, self, aux)
goto fail_tec;
}
+ if ((sc->sc_ih = bus_intr_establish(sa->sa_bustag, sa->sa_pri,
+ IPL_TTY, 0, cgsix_intr, sc)) == NULL) {
+ printf(": couldn't establish interrupt, pri %d\n", sa->sa_pri);
+ goto fail_intr;
+ }
+
/* if prom didn't initialize us, do it the hard way */
if (OF_getproplen(sa->sa_node, "width") != sizeof(u_int32_t))
cgsix_hardreset(sc);
@@ -350,7 +359,7 @@ cgsixattach(parent, self, aux)
sc->sc_height = getpropint(sa->sa_node, "height", 900);
sc->sc_width = getpropint(sa->sa_node, "width", 1152);
- sbus_establish(&sc->sc_sd, &sc->sc_dev);
+ sbus_establish(&sc->sc_sd, self);
sc->sc_rcons.rc_sp = &sc->sc_raster;
sc->sc_raster.width = sc->sc_width;
@@ -405,6 +414,8 @@ cgsixattach(parent, self, aux)
return;
+fail_intr:
+ bus_space_unmap(sa->sa_bustag, sc->sc_tec_regs, CGSIX_TEC_SIZE);
fail_tec:
bus_space_unmap(sa->sa_bustag, sc->sc_vid_regs, CGSIX_VID_SIZE);
fail_vid:
@@ -457,7 +468,7 @@ cgsix_ioctl(v, cmd, data, flags, p)
error = cg6_bt_putcmap(&sc->sc_cmap, cm);
if (error)
return (error);
- cgsix_loadcmap(sc, cm->index, cm->count);
+ cgsix_loadcmap_deferred(sc, cm->index, cm->count);
break;
case WSDISPLAYIO_SVIDEO:
@@ -606,7 +617,20 @@ cg6_bt_putcmap(bcm, rcm)
}
void
-cgsix_loadcmap(sc, start, ncolors)
+cgsix_loadcmap_deferred(sc, start, ncolors)
+ struct cgsix_softc *sc;
+ u_int start, ncolors;
+{
+ u_int32_t thcm;
+
+ thcm = THC_READ(sc, CG6_THC_MISC);
+ thcm &= ~THC_MISC_RESET;
+ thcm |= THC_MISC_INTEN;
+ THC_WRITE(sc, CG6_THC_MISC, thcm);
+}
+
+void
+cgsix_loadcmap_immediate(sc, start, ncolors)
struct cgsix_softc *sc;
u_int start, ncolors;
{
@@ -638,7 +662,7 @@ cgsix_setcolor(sc, index, r, g, b)
bcm->cm_map[index][0] = r;
bcm->cm_map[index][1] = g;
bcm->cm_map[index][2] = b;
- cgsix_loadcmap(sc, index, 1);
+ cgsix_loadcmap_immediate(sc, index, 1);
}
void
@@ -752,3 +776,25 @@ cgsix_burner(vsc, on, flags)
THC_WRITE(sc, CG6_THC_MISC, thcm);
splx(s);
}
+
+int
+cgsix_intr(vsc)
+ void *vsc;
+{
+ struct cgsix_softc *sc = vsc;
+ u_int32_t thcm;
+
+ thcm = THC_READ(sc, CG6_THC_MISC);
+ if ((thcm & (THC_MISC_INTEN | THC_MISC_INTR)) !=
+ (THC_MISC_INTEN | THC_MISC_INTR)) {
+ /* Not expecting an interrupt, it's not for us. */
+ return (0);
+ }
+
+ /* Acknowledge the interrupt and disable it. */
+ thcm &= ~(THC_MISC_RESET | THC_MISC_INTEN);
+ thcm |= THC_MISC_INTR;
+ THC_WRITE(sc, CG6_THC_MISC, thcm);
+ cgsix_loadcmap_immediate(sc, 0, 256);
+ return (1);
+}