summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2017-08-27 12:42:23 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2017-08-27 12:42:23 +0000
commit52004fdc7f039354116cfffa13fd53937398d606 (patch)
treea0b717b59e3315796bc8d39f8ebd0e02dd20243a /sys/dev
parentb6c82a4368d687d945dda9021d20427474b78503 (diff)
Add glass console support for arm64. This uses the "stdout-path" property
of the /chosen node in the device tree to decide whether the framebuffer should be used as the console device. Most, if not all, machines will have that set to use a serial console and there is no easy way yet to change that. ok jsg@
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/fdt/simplefb.c160
1 files changed, 127 insertions, 33 deletions
diff --git a/sys/dev/fdt/simplefb.c b/sys/dev/fdt/simplefb.c
index 2a3e1c7d715..893dafea658 100644
--- a/sys/dev/fdt/simplefb.c
+++ b/sys/dev/fdt/simplefb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: simplefb.c,v 1.1 2017/01/03 19:57:01 kettenis Exp $ */
+/* $OpenBSD: simplefb.c,v 1.2 2017/08/27 12:42:22 kettenis Exp $ */
/*
* Copyright (c) 2016 Mark Kettenis
*
@@ -29,6 +29,9 @@
#include <dev/wscons/wsdisplayvar.h>
#include <dev/rasops/rasops.h>
+#define SIMPLEFB_WIDTH 160
+#define SIMPLEFB_HEIGHT 50
+
struct simplefb_format {
const char *format;
int depth;
@@ -46,9 +49,10 @@ struct simplefb_format simplefb_formats[] = {
{ "x1r5g5b5", 15 },
{ "a1r5g5b5", 15 },
{ "r8g8b8", 24 },
- { "x8r8g8b8", 32 },
- { "a8r8g8b8", 32 },
- { "a8b8g8r8", 32, 0, 8, 8, 8, 16, 8 }
+ { "x8r8g8b8", 32, 16, 8, 8, 8, 0, 8 },
+ { "a8r8g8b8", 32, 16, 8, 8, 8, 0, 8 },
+ { "x8b8g8r8", 32 },
+ { "a8b8g8r8", 32 }
};
struct simplefb_softc {
@@ -66,6 +70,10 @@ struct simplefb_softc {
psize_t sc_psize;
};
+struct rasops_info simplefb_ri;
+struct wsscreen_descr simplefb_wsd = { "std" };
+struct wsdisplay_charcell simplefb_bs[SIMPLEFB_WIDTH * SIMPLEFB_HEIGHT];
+
int simplefb_match(struct device *, void *, void *);
void simplefb_attach(struct device *, struct device *, void *);
@@ -77,6 +85,8 @@ struct cfdriver simplefb_cd = {
NULL, "simplefb", DV_DULL
};
+const char *simplefb_init(int, struct rasops_info *);
+
int simplefb_wsioctl(void *, u_long, caddr_t, int, struct proc *);
paddr_t simplefb_wsmmap(void *, off_t, int);
int simplefb_alloc_screen(void *, const struct wsscreen_descr *,
@@ -108,52 +118,44 @@ simplefb_attach(struct device *parent, struct device *self, void *aux)
struct fdt_attach_args *faa = aux;
struct rasops_info *ri = &sc->sc_ri;
struct wsemuldisplaydev_attach_args waa;
- char format[16];
- int i;
+ const char *format;
+ int console = 0;
+ long defattr;
if (faa->fa_nreg < 1)
return;
- format[0] = 0;
- OF_getprop(faa->fa_node, "format", format, sizeof(format));
- format[sizeof(format) - 1] = 0;
-
- for (i = 0; i < nitems(simplefb_formats); i++) {
- if (strcmp(format, simplefb_formats[i].format) == 0) {
- sc->sc_format = &simplefb_formats[i];
- break;
- }
- }
- if (sc->sc_format == NULL) {
+ format = simplefb_init(faa->fa_node, ri);
+ if (format) {
printf(": unsupported format \"%s\"\n", format);
return;
}
+ if (faa->fa_node == stdout_node)
+ console = 1;
+
sc->sc_iot = faa->fa_iot;
sc->sc_paddr = faa->fa_reg[0].addr;
sc->sc_psize = faa->fa_reg[0].size;
if (bus_space_map(sc->sc_iot, sc->sc_paddr, sc->sc_psize,
- BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE, &sc->sc_ioh))
- panic("%s: bus_space_map failed!", __func__);
-
- ri->ri_width = OF_getpropint(faa->fa_node, "width", 0);
- ri->ri_height = OF_getpropint(faa->fa_node, "height", 0);
- ri->ri_stride = OF_getpropint(faa->fa_node, "stride", 0);
- ri->ri_depth = sc->sc_format->depth;
- ri->ri_rpos = sc->sc_format->rpos;
- ri->ri_rnum = sc->sc_format->rnum;
- ri->ri_gpos = sc->sc_format->gpos;
- ri->ri_gnum = sc->sc_format->gnum;
- ri->ri_bpos = sc->sc_format->bpos;
- ri->ri_bnum = sc->sc_format->bnum;
- ri->ri_flg = RI_CENTER | RI_CLEAR | RI_FULLCLEAR;
- ri->ri_flg |= RI_VCONS | RI_WRONLY;
+ BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE, &sc->sc_ioh)) {
+ printf(": can't map framebuffer\n");
+ return;
+ }
+
ri->ri_bits = bus_space_vaddr(sc->sc_iot, sc->sc_ioh);
ri->ri_hw = sc;
+ if (console) {
+ /* Preserve contents. */
+ ri->ri_bs = simplefb_bs;
+ ri->ri_flg &= ~RI_CLEAR;
+ }
+
printf(": %dx%d\n", ri->ri_width, ri->ri_height);
- rasops_init(ri, 160, 160);
+ ri->ri_flg |= RI_VCONS;
+ rasops_init(ri, SIMPLEFB_HEIGHT, SIMPLEFB_WIDTH);
strlcpy(sc->sc_wsd.name, "std", sizeof(sc->sc_wsd.name));
sc->sc_wsd.capabilities = ri->ri_caps;
@@ -167,15 +169,57 @@ simplefb_attach(struct device *parent, struct device *self, void *aux)
sc->sc_wsl.nscreens = 1;
sc->sc_wsl.screens = (const struct wsscreen_descr **)sc->sc_scrlist;
+ if (console) {
+ ri->ri_ops.alloc_attr(ri->ri_active, 0, 0, 0, &defattr);
+ wsdisplay_cnattach(&sc->sc_wsd, ri->ri_active,
+ simplefb_ri.ri_ccol, simplefb_ri.ri_crow, defattr);
+ }
+
memset(&waa, 0, sizeof(waa));
waa.scrdata = &sc->sc_wsl;
waa.accessops = &simplefb_accessops;
waa.accesscookie = ri;
+ waa.console = console;
config_found_sm(self, &waa, wsemuldisplaydevprint,
wsemuldisplaydevsubmatch);
}
+const char *
+simplefb_init(int node, struct rasops_info *ri)
+{
+ struct simplefb_format *fmt = NULL;
+ static char format[16];
+ int i;
+
+ format[0] = 0;
+ OF_getprop(node, "format", format, sizeof(format));
+ format[sizeof(format) - 1] = 0;
+
+ for (i = 0; i < nitems(simplefb_formats); i++) {
+ if (strcmp(format, simplefb_formats[i].format) == 0) {
+ fmt = &simplefb_formats[i];
+ break;
+ }
+ }
+ if (fmt == NULL)
+ return format;
+
+ ri->ri_width = OF_getpropint(node, "width", 0);
+ ri->ri_height = OF_getpropint(node, "height", 0);
+ ri->ri_stride = OF_getpropint(node, "stride", 0);
+ ri->ri_depth = fmt->depth;
+ ri->ri_rpos = fmt->rpos;
+ ri->ri_rnum = fmt->rnum;
+ ri->ri_gpos = fmt->gpos;
+ ri->ri_gnum = fmt->gnum;
+ ri->ri_bpos = fmt->bpos;
+ ri->ri_bnum = fmt->bnum;
+ ri->ri_flg = RI_CENTER | RI_CLEAR | RI_FULLCLEAR | RI_WRONLY;
+
+ return NULL;
+}
+
int
simplefb_wsioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
{
@@ -241,3 +285,53 @@ simplefb_alloc_screen(void *v, const struct wsscreen_descr *type,
{
return rasops_alloc_screen(v, cookiep, curxp, curyp, attrp);
}
+
+#include "ukbd.h"
+
+#if NUKBD > 0
+#include <dev/usb/ukbdvar.h>
+#endif
+
+void
+simplefb_init_cons(bus_space_tag_t iot)
+{
+ struct rasops_info *ri = &simplefb_ri;
+ bus_space_handle_t ioh;
+ struct fdt_reg reg;
+ void *node;
+ long defattr = 0;
+
+ node = fdt_find_cons("simple-framebuffer");
+ if (node == NULL)
+ return;
+
+ if (fdt_get_reg(node, 0, &reg))
+ return;
+
+ if (bus_space_map(iot, reg.addr, reg.size,
+ BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE, &ioh))
+ return;
+
+ ri->ri_bits = bus_space_vaddr(iot, ioh);
+
+ if (simplefb_init(stdout_node, ri))
+ return;
+
+ ri->ri_bs = simplefb_bs;
+ rasops_init(ri, SIMPLEFB_HEIGHT, SIMPLEFB_WIDTH);
+
+ simplefb_wsd.capabilities = ri->ri_caps;
+ simplefb_wsd.ncols = ri->ri_cols;
+ simplefb_wsd.nrows = ri->ri_rows;
+ simplefb_wsd.textops = &ri->ri_ops;
+ simplefb_wsd.fontwidth = ri->ri_font->fontwidth;
+ simplefb_wsd.fontheight = ri->ri_font->fontheight;
+
+ ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr);
+ wsdisplay_cnattach(&simplefb_wsd, ri, 0, 0, defattr);
+
+#if NUKBD > 0
+ /* Allow USB keyboards to become the console input device. */
+ ukbd_cnattach();
+#endif
+}