summaryrefslogtreecommitdiff
path: root/sys/arch/pmax/dev/sfb.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/pmax/dev/sfb.c')
-rw-r--r--sys/arch/pmax/dev/sfb.c134
1 files changed, 92 insertions, 42 deletions
diff --git a/sys/arch/pmax/dev/sfb.c b/sys/arch/pmax/dev/sfb.c
index 89cd89a4b3d..1e744970f3d 100644
--- a/sys/arch/pmax/dev/sfb.c
+++ b/sys/arch/pmax/dev/sfb.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sfb.c,v 1.4 1995/09/12 07:30:45 jonathan Exp $ */
+/* $NetBSD: sfb.c,v 1.11.4.3 1996/09/09 20:47:40 thorpej Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -36,7 +36,6 @@
* SUCH DAMAGE.
*
* from: @(#)sfb.c 8.1 (Berkeley) 6/10/93
- * $Id: sfb.c,v 1.1 1995/10/18 08:51:28 deraadt Exp $
*/
/*
@@ -81,16 +80,19 @@
* rights to redistribute these changes.
*/
-#include <fb.h>
-#include <sfb.h>
+#include "fb.h"
+#include "sfb.h"
#include <sys/param.h>
+#include <sys/systm.h> /* printf() */
#include <sys/kernel.h>
#include <sys/errno.h>
#include <sys/device.h>
#include <sys/fcntl.h>
+#include <sys/malloc.h>
#include <machine/autoconf.h>
+#include <dev/tc/tcvar.h>
#include <machine/fbio.h>
#include <machine/fbvar.h>
@@ -117,16 +119,21 @@ extern int pmax_boardtype;
* Forward references.
*/
-int sfbinit (char *, int, int);
+int sfbinit __P((struct fbinfo *fi, caddr_t sfbaddr, int unit, int silent));
#define CMAP_BITS (3 * 256) /* 256 entries, 3 bytes per. */
-static u_char cmap_bits [NSFB * CMAP_BITS]; /* One colormap per sfb... */
+static u_char cmap_bits [CMAP_BITS]; /* colormap for console... */
int sfbmatch __P((struct device *, void *, void *));
void sfbattach __P((struct device *, struct device *, void *));
+int sfb_intr __P((void *sc));
-struct cfdriver sfbcd = {
- NULL, "sfb", sfbmatch, sfbattach, DV_DULL, sizeof(struct device), 0
+struct cfattach sfb_ca = {
+ sizeof(struct device), sfbmatch, sfbattach
+};
+
+struct cfdriver sfb_cd = {
+ NULL, "sfb", DV_DULL
};
struct fbdriver sfb_driver = {
@@ -149,28 +156,27 @@ sfbmatch(parent, match, aux)
void *match;
void *aux;
{
- struct cfdata *cf = match;
- struct confargs *ca = aux;
- static int nsfbs = 1;
- caddr_t sfbaddr = BUS_CVTADDR(ca);
+ /*struct cfdata *cf = match;*/
+ struct tc_attach_args *ta = aux;
/* make sure that we're looking for this type of device. */
- /*if (!sfbprobe(sfbaddr)) return 0;*/
- if (!BUS_MATCHNAME(ca, "PMAGB-BA"))
+ if (!TC_BUS_MATCHNAME(ta, "PMAGB-BA"))
return (0);
-
-#ifdef notyet
- /* if it can't have the one mentioned, reject it */
- if (cf->cf_unit >= nsfbs)
+ /*
+ * if the TC rom ident matches, assume the VRAM is present too.
+ */
+#if 0
+ if (badaddr( ((caddr_t)ta->ta_addr) + SFB_OFFSET_VRAM, 4))
return (0);
#endif
+
return (1);
}
/*
* Attach a device. Hand off all the work to sfbinit(),
- * so console-config cod can attach sfbs early in boot.
+ * so console-config code can attach sfbs early in boot.
*/
void
sfbattach(parent, self, aux)
@@ -178,51 +184,70 @@ sfbattach(parent, self, aux)
struct device *self;
void *aux;
{
- struct confargs *ca = aux;
- caddr_t base = BUS_CVTADDR(ca);
+ struct tc_attach_args *ta = aux;
+ caddr_t sfbaddr = (caddr_t)ta->ta_addr;
int unit = self->dv_unit;
+ struct fbinfo *fi = (struct fbinfo *) self;
#ifdef notyet
/* if this is the console, it's already configured. */
- if (ca->ca_slotpri == cons_slot)
+ if (ta->ta_cookie == cons_slot)
return; /* XXX patch up f softc pointer */
#endif
- if (!sfbinit(base, unit, 0))
+ if (!sfbinit(fi, sfbaddr, unit, 0))
return;
#if 0 /*XXX*/
- *(base + SFB_INTERRUPT_ENABLE) = 0;
-#endif
-}
+ /*
+ * Sean Davidson (davidson@sean.zk3.dec.com) reports this
+ * isn't sufficient on a 3MIN, Use an interrupt handler instead.
+ */
-/*
- * Test to see if device is present.
- * Return true if found and initialized ok.
- */
-/*ARGSUSED*/
-sfbprobe(cp)
- struct pmax_ctlr *cp;
-{
+ *(sfbaddr + SFB_INTERRUPT_ENABLE) = 0;
+
+#endif
+ /*
+ * By default, the SFB requests an interrupt during every vertical-retrace period.
+ * We never enable interrupts from SFB cards, except on the
+ * 3MIN, where TC options interrupt at spl0 through spl2, and
+ * disabling of TC option interrupts doesn't work.
+ */
+ if (pmax_boardtype == DS_3MIN) {
+ tc_intr_establish(parent, (void*)ta->ta_cookie, TC_IPL_NONE,
+ sfb_intr, fi);
+ }
+ printf("\n");
}
+
/*
* Initialization
*/
int
-sfbinit(base, unit, silent)
+sfbinit(fi, base, unit, silent)
+ struct fbinfo *fi;
char *base;
int unit;
int silent;
{
- struct fbinfo *fi;
- u_char foo;
-
- fi = &sfbfi; /* XXX use softc */
- if (unit > NSFB)
- return (0);
+ /*
+ * If this device is being intialized as the console, malloc()
+ * is not yet up and we must use statically-allocated space.
+ */
+ if (fi == NULL) {
+ fi = &sfbfi; /* XXX */
+ fi->fi_cmap_bits = (caddr_t)cmap_bits;
+ }
+ else {
+ fi->fi_cmap_bits = malloc(CMAP_BITS, M_DEVBUF, M_NOWAIT);
+ if (fi->fi_cmap_bits == NULL) {
+ printf("sfb%d: no memory for cmap\n", unit);
+ return (0);
+ }
+ }
/* check for no frame buffer */
if (badaddr(base + SFB_OFFSET_VRAM, 4))
@@ -238,7 +263,6 @@ sfbinit(base, unit, silent)
fi->fi_linebytes = 1280;
fi->fi_driver = &sfb_driver;
fi->fi_blanked = 0;
- fi->fi_cmap_bits = (caddr_t)&cmap_bits [CMAP_BITS * unit];
/* Fill in Frame Buffer Type struct. */
fi->fi_type.fb_boardtype = PMAX_FBTYPE_SFB;
@@ -298,4 +322,30 @@ sfbinit(base, unit, silent)
return (1);
}
+
+/*
+ * The TURBOChannel sfb interrupts by default on every vertical retrace,
+ * and we don't know to disable those interrupt requests.
+ * The 4.4BSD/pamx kernel never enabled delivery of those interrupts from the TC bus,
+ * but there's a kernel design bug on the 3MIN, where disabling
+ * (or enabling) TC option interrupts has no effect; each slot interrupt is
+ * mapped directly to a separate R3000 interrupt and they always seem to be taken.
+ *
+ * This function simply dismisses SFB interrupts, or the interrupt
+ * request from the card will still be active.
+ */
+int
+sfb_intr(sc)
+ void *sc;
+{
+ struct fbinfo *fi = /* XXX (struct fbinfo *)sc */ &sfbfi;
+
+ char *slot_addr = (((char *)fi->fi_base) - SFB_ASIC_OFFSET);
+
+ /* reset vertical-retrace interrupt by writing a dont-care */
+ *(int*) (slot_addr + SFB_CLEAR) = 0;
+
+ return (0);
+}
+
/* old bt459 code used to be here */