summaryrefslogtreecommitdiff
path: root/sys/arch/sparc/dev/p9100.c
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2005-03-26 15:16:15 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2005-03-26 15:16:15 +0000
commit3dd9fd567c469f5c2397f45643c6712fb799f93c (patch)
tree823705f7510e2d546f2520e044049fd5a006def1 /sys/arch/sparc/dev/p9100.c
parent3ddb54fae865deadc130c66fcc5167b3fde0f8b6 (diff)
Use the PROM font whenever possible, rather than switching to the
not-so-nice 8x16 font upon attach. Also, shift the display two character cells to the left from its centered position in this case, so as to keep our output properly aligned with the PROM messages. Tested on 3GS and 3GX.
Diffstat (limited to 'sys/arch/sparc/dev/p9100.c')
-rw-r--r--sys/arch/sparc/dev/p9100.c117
1 files changed, 100 insertions, 17 deletions
diff --git a/sys/arch/sparc/dev/p9100.c b/sys/arch/sparc/dev/p9100.c
index b8f5aca9970..ce922b4f8ee 100644
--- a/sys/arch/sparc/dev/p9100.c
+++ b/sys/arch/sparc/dev/p9100.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: p9100.c,v 1.35 2005/03/23 17:16:34 miod Exp $ */
+/* $OpenBSD: p9100.c,v 1.36 2005/03/26 15:16:14 miod Exp $ */
/*
- * Copyright (c) 2003, Miodrag Vallat.
+ * Copyright (c) 2003, 2005, Miodrag Vallat.
* Copyright (c) 1999 Jason L. Wright (jason@thought.net)
* All rights reserved.
*
@@ -46,6 +46,7 @@
#include <uvm/uvm_extern.h>
#include <machine/autoconf.h>
+#include <machine/bsd_openprom.h>
#include <machine/pmap.h>
#include <machine/cpu.h>
#include <machine/conf.h>
@@ -53,6 +54,7 @@
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsdisplayvar.h>
#include <dev/rasops/rasops.h>
+#include <dev/wsfont/wsfont.h>
#include <machine/fbvar.h>
#include <sparc/dev/btreg.h>
@@ -85,6 +87,7 @@ static __inline__
void p9100_loadcmap_deferred(struct p9100_softc *, u_int, u_int);
void p9100_loadcmap_immediate(struct p9100_softc *, u_int, u_int);
paddr_t p9100_mmap(void *, off_t, int);
+int p9100_pick_romfont(struct p9100_softc *);
void p9100_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
struct wsdisplay_accessops p9100_accessops = {
@@ -225,9 +228,10 @@ void
p9100attach(struct device *parent, struct device *self, void *args)
{
struct p9100_softc *sc = (struct p9100_softc *)self;
+ struct rasops_info *ri = &sc->sc_sunfb.sf_ro;
struct confargs *ca = args;
- int node, row, scr;
- int isconsole, fb_depth;
+ int node, scr, fb_depth;
+ int isconsole, fontswitch, clear;
#ifdef DIAGNOSTIC
if (ca->ca_ra.ra_nreg < P9100_NREG) {
@@ -269,9 +273,9 @@ p9100attach(struct device *parent, struct device *self, void *args)
break;
}
fb_setsize(&sc->sc_sunfb, fb_depth, 800, 600, node, ca->ca_bustype);
- sc->sc_sunfb.sf_ro.ri_bits = mapiodev(&sc->sc_phys, 0,
+ ri->ri_bits = mapiodev(&sc->sc_phys, 0,
round_page(sc->sc_sunfb.sf_fbsize));
- sc->sc_sunfb.sf_ro.ri_hw = sc;
+ ri->ri_hw = sc;
printf(": rev %x, %dx%d, depth %d\n", scr & SCR_ID_MASK,
sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height,
@@ -287,9 +291,13 @@ p9100attach(struct device *parent, struct device *self, void *args)
P9100_WRITE_CTL(sc, P9000_INTERRUPT_ENABLE, IER_MASTER_ENABLE | 0);
/*
- * 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:
+ * Try to get a copy of the PROM font.
+ *
+ * If we can, we still need to adjust the visible portion of the
+ * display, as the PROM output is offset two chars to the left.
+ *
+ * If we can't, we'll switch to the 8x16 font, and we'll need to adjust
+ * two things:
* - 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,
@@ -297,8 +305,13 @@ p9100attach(struct device *parent, struct device *self, void *args)
* the margins.
* XXX there should be a rasops "clear margins" feature
*/
- fbwscons_init(&sc->sc_sunfb,
- isconsole && (sc->sc_sunfb.sf_width >= 1024) ? 0 : RI_CLEAR);
+ fontswitch = p9100_pick_romfont(sc);
+ clear = !isconsole || fontswitch;
+ fbwscons_init(&sc->sc_sunfb, clear ? RI_CLEAR : 0);
+ if (!clear) {
+ ri->ri_bits -= 2 * ri->ri_xscale;
+ ri->ri_xorigin -= 2 * ri->ri_xscale;
+ }
fbwscons_setcolormap(&sc->sc_sunfb, p9100_setcolor);
/*
@@ -313,12 +326,7 @@ p9100attach(struct device *parent, struct device *self, void *args)
p9100_burner(sc, 1, 0);
if (isconsole) {
- if (sc->sc_sunfb.sf_width < 1024)
- row = 0; /* screen has been cleared above */
- else
- row = -1;
-
- fbwscons_console_init(&sc->sc_sunfb, row);
+ fbwscons_console_init(&sc->sc_sunfb, clear ? 0 : -1);
}
fbwscons_attach(&sc->sc_sunfb, &p9100_accessops, isconsole);
@@ -752,3 +760,78 @@ p9100_ras_do_cursor(struct rasops_info *ri)
p9100_drain(sc);
}
+
+/*
+ * PROM font managment
+ */
+
+#define ROMFONTNAME "p9100_romfont"
+struct wsdisplay_font p9100_romfont = {
+ ROMFONTNAME,
+ 0,
+ 0, 256,
+ WSDISPLAY_FONTENC_ISO, /* should check the `character-set' property */
+ 0, 0, 0,
+ WSDISPLAY_FONTORDER_L2R,
+ WSDISPLAY_FONTORDER_L2R,
+ NULL,
+ NULL
+};
+
+int
+p9100_pick_romfont(struct p9100_softc *sc)
+{
+ struct rasops_info *ri = &sc->sc_sunfb.sf_ro;
+ int *romwidth, *romheight;
+ u_int8_t **romaddr;
+ char buf[200];
+
+ /*
+ * This code currently only works for PROM >= 2.9; see
+ * autoconf.c romgetcursoraddr() for details.
+ */
+ if (promvec->pv_romvec_vers < 2 || promvec->pv_printrev < 0x00020009)
+ return (1);
+
+ /*
+ * Get the PROM font metrics and address
+ */
+ snprintf(buf, sizeof buf, "stdout @ is my-self "
+ "addr char-height %lx ! addr char-width %lx ! addr font-base %lx !",
+ (vaddr_t)&romheight, (vaddr_t)&romwidth, (vaddr_t)&romaddr);
+ romheight = romwidth = NULL;
+ rominterpret(buf);
+
+ if (romheight == NULL || romwidth == NULL || romaddr == NULL ||
+ *romheight == 0 || *romwidth == 0 || *romaddr == NULL)
+ return (1);
+
+ p9100_romfont.fontwidth = *romwidth;
+ p9100_romfont.fontheight = *romheight;
+ p9100_romfont.stride = howmany(*romwidth, NBBY);
+ p9100_romfont.data = *romaddr;
+
+#ifdef DEBUG
+ printf("%s: PROM font %dx%d @%p",
+ sc->sc_sunfb.sf_dev.dv_xname, *romwidth, *romheight, *romaddr);
+#endif
+
+ /*
+ * Build and add a wsfont structure
+ */
+ wsfont_init(); /* if not done before */
+ if (wsfont_add(&p9100_romfont, 0) != 0)
+ return (1);
+
+ /*
+ * Select this very font in our rasops structure
+ */
+ ri->ri_wsfcookie = wsfont_find(ROMFONTNAME, 0, 0, 0);
+ if (wsfont_lock(ri->ri_wsfcookie, &ri->ri_font,
+ WSDISPLAY_FONTORDER_L2R, WSDISPLAY_FONTORDER_L2R) <= 0) {
+ ri->ri_wsfcookie = 0;
+ return (1);
+ }
+
+ return (0);
+}