summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/sparc/dev/p9100.c103
1 files changed, 73 insertions, 30 deletions
diff --git a/sys/arch/sparc/dev/p9100.c b/sys/arch/sparc/dev/p9100.c
index b7b43b7453c..48b7b247a07 100644
--- a/sys/arch/sparc/dev/p9100.c
+++ b/sys/arch/sparc/dev/p9100.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: p9100.c,v 1.11 2002/11/06 21:06:20 miod Exp $ */
+/* $OpenBSD: p9100.c,v 1.12 2003/05/12 18:57:14 miod Exp $ */
/*
* Copyright (c) 1999 Jason L. Wright (jason@thought.net)
@@ -130,6 +130,14 @@ struct cfdriver pnozz_cd = {
};
/*
+ * SBus registers mappings
+ */
+#define P9100_NREG 3
+#define P9100_REG_CTL 0
+#define P9100_REG_CMD 1
+#define P9100_REG_VRAM 2
+
+/*
* System control and command registers
* (IBM RGB528 RamDac, p9100, video coprocessor)
*/
@@ -138,6 +146,13 @@ struct p9100_ctl {
struct p9100_scr {
volatile u_int32_t unused0;
volatile u_int32_t scr; /* system config reg */
+#define SCR_ID_MASK 0x00000007
+#define SCR_PIXEL_ID_MASK 0x00000007
+#define SCR_PIXEL_MASK 0x1c000000
+#define SCR_PIXEL_8BPP 0x08000000
+#define SCR_PIXEL_16BPP 0x0c000000
+#define SCR_PIXEL_24BPP 0x1c000000
+#define SCR_PIXEL_32BPP 0x14000000
volatile u_int32_t ir; /* interrupt reg */
volatile u_int32_t ier; /* interrupt enable */
volatile u_int32_t arbr; /* alt read bank reg */
@@ -247,43 +262,71 @@ p9100attach(parent, self, args)
struct p9100_softc *sc = (struct p9100_softc *)self;
struct confargs *ca = args;
struct wsemuldisplaydev_attach_args waa;
- int node = 0, i;
- int isconsole, fb_depth, fb_cmsize;
- char *cp;
+ int node, row, scr;
+ int isconsole, fb_depth;
+
+#ifdef DIAGNOSTIC
+ if (ca->ca_ra.ra_nreg < P9100_NREG) {
+ printf(": expected %d registers, got only %d\n",
+ P9100_NREG, ca->ca_ra.ra_nreg);
+ return;
+ }
+#endif
sc->sc_sunfb.sf_flags = self->dv_cfdata->cf_flags;
- sc->sc_phys = ca->ca_ra.ra_reg[2];
+ sc->sc_phys = ca->ca_ra.ra_reg[P9100_REG_VRAM];
- sc->sc_ctl = mapiodev(&(ca->ca_ra.ra_reg[0]), 0,
+ sc->sc_ctl = mapiodev(&(ca->ca_ra.ra_reg[P9100_REG_CTL]), 0,
ca->ca_ra.ra_reg[0].rr_len);
- sc->sc_cmd = mapiodev(&(ca->ca_ra.ra_reg[1]), 0,
+ sc->sc_cmd = mapiodev(&(ca->ca_ra.ra_reg[P9100_REG_CMD]), 0,
ca->ca_ra.ra_reg[1].rr_len);
node = ca->ca_ra.ra_node;
isconsole = node == fbnode;
P9100_SELECT_SCR(sc);
- i = sc->sc_ctl->ctl_scr.scr;
- switch ((i >> 26) & 7) {
- case 5:
+ scr = sc->sc_ctl->ctl_scr.scr;
+ switch (scr & SCR_PIXEL_MASK) {
+ case SCR_PIXEL_32BPP:
fb_depth = 32;
break;
- case 7:
+ case SCR_PIXEL_24BPP:
fb_depth = 24;
break;
- case 3:
+ case SCR_PIXEL_16BPP:
fb_depth = 16;
break;
- case 2:
default:
+#ifdef DIAGNOSTIC
+ printf(": unknown color depth code 0x%x, assuming 8\n%s",
+ scr & SCR_PIXEL_MASK, self->dv_xname);
+#endif
+ case SCR_PIXEL_8BPP:
fb_depth = 8;
break;
}
fb_setsize(&sc->sc_sunfb, fb_depth, 800, 600, node, ca->ca_bustype);
- sc->sc_sunfb.sf_ro.ri_bits = mapiodev(&(ca->ca_ra.ra_reg[2]), 0,
+ sc->sc_sunfb.sf_ro.ri_bits = mapiodev(&sc->sc_phys, 0,
round_page(sc->sc_sunfb.sf_fbsize));
sc->sc_sunfb.sf_ro.ri_hw = sc;
- fbwscons_init(&sc->sc_sunfb, isconsole);
+
+ printf(": rev %x, %dx%d, depth %d\n", scr & SCR_ID_MASK,
+ sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height,
+ sc->sc_sunfb.sf_depth);
+
+ /*
+ * 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));
fbwscons_setcolormap(&sc->sc_sunfb, p9100_setcolor);
p9100_stdscreen.capabilities = sc->sc_sunfb.sf_ro.ri_caps;
@@ -291,25 +334,25 @@ p9100attach(parent, self, args)
p9100_stdscreen.ncols = sc->sc_sunfb.sf_ro.ri_cols;
p9100_stdscreen.textops = &sc->sc_sunfb.sf_ro.ri_ops;
- printf(": rev %x, %dx%d, depth %d\n", i & 7,
- sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height,
- sc->sc_sunfb.sf_depth);
-
sbus_establish(&sc->sc_sd, &sc->sc_sunfb.sf_dev);
- /* initialize color map */
- fb_cmsize = getpropint(node, "cmsize", 256);
- cp = &sc->sc_cmap.cm_map[0][0];
- cp[0] = cp[1] = cp[2] = 0;
- for (i = 1, cp = &sc->sc_cmap.cm_map[i][0]; i < fb_cmsize; cp += 3, i++)
- cp[0] = cp[1] = cp[2] = 0xff;
- p9100_loadcmap(sc, 0, 256);
-
/* enable video */
p9100_burner(sc, 1, 0);
if (isconsole) {
- fbwscons_console_init(&sc->sc_sunfb, &p9100_stdscreen, -1,
+ switch (sc->sc_sunfb.sf_width) {
+ case 640:
+ row = p9100_stdscreen.nrows - 1;
+ break;
+ case 800:
+ row = 0; /* screen has been cleared above */
+ break;
+ default:
+ row = -1;
+ break;
+ }
+
+ fbwscons_console_init(&sc->sc_sunfb, &p9100_stdscreen, row,
p9100_burner);
}
@@ -474,7 +517,7 @@ p9100_loadcmap(sc, start, ncolors)
P9100_SELECT_VRAM(sc);
P9100_SELECT_VRAM(sc);
- sc->sc_junk = sc->sc_ctl->ctl_dac.pwraddr;
+ P9100_SELECT_DAC(sc);
sc->sc_ctl->ctl_dac.pwraddr = start << 16;
for (p = sc->sc_cmap.cm_map[start], ncolors *= 3; ncolors-- > 0; p++) {
@@ -482,7 +525,7 @@ p9100_loadcmap(sc, start, ncolors)
P9100_SELECT_VRAM(sc);
P9100_SELECT_VRAM(sc);
- sc->sc_junk = sc->sc_ctl->ctl_dac.paldata;
+ P9100_SELECT_DAC(sc);
sc->sc_ctl->ctl_dac.paldata = (*p) << 16;
}
}