Here is a fun little driver that supports the framebuffer that u-boot sets up for us on the sunxi platform. The mainbus(4) changes are necessary, because the framebuffer device tree node actually lives under /chosen, so we don't pick it up during the normal device tree walk. The most common 15/16 bpp, 24 bpp and 32 bpp modes are supported, although I think u-boot always uses 32 bpp on sunxi hardware. No console support (yet) so simplefb is not added to RAMDISK kernels.
On other plaforms (imx for example) u-boot does set up the framebuffer, but doesn't add the appropriate simplefb nodes to the device tree. That could be added though and I wouldn't expect this to be a big effort. ok? Index: arch/arm/mainbus/mainbus.c =================================================================== RCS file: /cvs/src/sys/arch/arm/mainbus/mainbus.c,v retrieving revision 1.13 diff -u -p -r1.13 mainbus.c --- arch/arm/mainbus/mainbus.c 6 Aug 2016 00:04:39 -0000 1.13 +++ arch/arm/mainbus/mainbus.c 2 Jan 2017 22:07:42 -0000 @@ -30,6 +30,7 @@ int mainbus_match(struct device *, void void mainbus_attach(struct device *, struct device *, void *); void mainbus_attach_node(struct device *, int); +void mainbus_attach_framebuffer(struct device *); int mainbus_legacy_search(struct device *, void *, void *); @@ -133,12 +134,10 @@ mainbus_attach(struct device *parent, st } /* Scan the whole tree. */ - for (node = OF_child(node); - node != 0; - node = OF_peer(node)) - { + for (node = OF_child(node); node != 0; node = OF_peer(node)) mainbus_attach_node(self, node); - } + + mainbus_attach_framebuffer(self); } /* @@ -212,6 +211,18 @@ mainbus_attach_node(struct device *self, free(fa.fa_reg, M_DEVBUF, fa.fa_nreg * sizeof(struct fdt_reg)); free(fa.fa_intr, M_DEVBUF, fa.fa_nintr * sizeof(uint32_t)); +} + +void +mainbus_attach_framebuffer(struct device *self) +{ + int node = OF_finddevice("/chosen"); + + if (node == 0) + return; + + for (node = OF_child(node); node != 0; node = OF_peer(node)) + mainbus_attach_node(self, node); } /* Index: arch/armv7/conf/GENERIC =================================================================== RCS file: /cvs/src/sys/arch/armv7/conf/GENERIC,v retrieving revision 1.69 diff -u -p -r1.69 GENERIC --- arch/armv7/conf/GENERIC 23 Oct 2016 18:50:34 -0000 1.69 +++ arch/armv7/conf/GENERIC 2 Jan 2017 22:07:42 -0000 @@ -108,6 +108,9 @@ virtio* at fdt? psci* at fdt? +simplefb* at fdt? +wsdisplay* at simplefb? + # Exynos exynos0 at mainbus? exdisplay* at exynos? Index: arch/armv7/conf/files.armv7 =================================================================== RCS file: /cvs/src/sys/arch/armv7/conf/files.armv7,v retrieving revision 1.28 diff -u -p -r1.28 files.armv7 --- arch/armv7/conf/files.armv7 9 Oct 2016 23:46:23 -0000 1.28 +++ arch/armv7/conf/files.armv7 2 Jan 2017 22:07:42 -0000 @@ -65,6 +65,9 @@ include "dev/gpio/files.gpio" # Machine-independent 1-Wire drivers include "dev/onewire/files.onewire" +# Machine-independent FDT drivers +include "dev/fdt/files.fdt" + # SoC includes include "arch/armv7/imx/files.imx" include "arch/armv7/omap/files.omap" Index: dev/fdt/files.fdt =================================================================== RCS file: dev/fdt/files.fdt diff -N dev/fdt/files.fdt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ dev/fdt/files.fdt 2 Jan 2017 22:07:45 -0000 @@ -0,0 +1,8 @@ +# $OpenBSD$ +# +# Config file and device description for machine-independent FDT code. +# Included by ports that need it. + +device simplefb: wsemuldisplaydev, rasops15, rasops16, rasops24, rasops32 +attach simplefb at fdt +file dev/fdt/simplefb.c simplefb Index: dev/fdt/simplefb.c =================================================================== RCS file: dev/fdt/simplefb.c diff -N dev/fdt/simplefb.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ dev/fdt/simplefb.c 2 Jan 2017 22:07:45 -0000 @@ -0,0 +1,243 @@ +/* $OpenBSD$ */ +/* + * Copyright (c) 2016 Mark Kettenis + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> + +#include <machine/bus.h> +#include <machine/fdt.h> + +#include <dev/ofw/openfirm.h> +#include <dev/ofw/fdt.h> + +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/wsdisplayvar.h> +#include <dev/rasops/rasops.h> + +struct simplefb_format { + const char *format; + int depth; + int rpos, rnum; + int gpos, gnum; + int bpos, bnum; +}; + +/* + * Supported pixel formats. Layout ommitted when it matches the + * rasops defaults. + */ +struct simplefb_format simplefb_formats[] = { + { "r5g6b5", 16 }, + { "x1r5g5b5", 15 }, + { "a1r5g5b5", 15 }, + { "r8g8b8", 24 }, + { "x8r8g8b8", 32 }, + { "a8r8g8b8", 32 }, + { "a8b8g8r8", 32, 0, 8, 8, 8, 16, 8 } +}; + +struct simplefb_softc { + struct device sc_dev; + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + + struct rasops_info sc_ri; + struct wsscreen_descr sc_wsd; + struct wsscreen_list sc_wsl; + struct wsscreen_descr *sc_scrlist[1]; + + struct simplefb_format *sc_format; + paddr_t sc_paddr; + psize_t sc_psize; +}; + +int simplefb_match(struct device *, void *, void *); +void simplefb_attach(struct device *, struct device *, void *); + +struct cfattach simplefb_ca = { + sizeof(struct simplefb_softc), simplefb_match, simplefb_attach +}; + +struct cfdriver simplefb_cd = { + NULL, "simplefb", DV_DULL +}; + +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 *, + void **, int *, int *, long *); + +struct wsdisplay_accessops simplefb_accessops = { + .ioctl = simplefb_wsioctl, + .mmap = simplefb_wsmmap, + .alloc_screen = simplefb_alloc_screen, + .free_screen = rasops_free_screen, + .show_screen = rasops_show_screen, + .getchar = rasops_getchar, + .load_font = rasops_load_font, + .list_font = rasops_list_font, +}; + +int +simplefb_match(struct device *parent, void *match, void *aux) +{ + struct fdt_attach_args *faa = aux; + + return OF_is_compatible(faa->fa_node, "simple-framebuffer"); +} + +void +simplefb_attach(struct device *parent, struct device *self, void *aux) +{ + struct simplefb_softc *sc = (struct simplefb_softc *)self; + struct fdt_attach_args *faa = aux; + struct rasops_info *ri = &sc->sc_ri; + struct wsemuldisplaydev_attach_args waa; + char format[16]; + int i; + + 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) { + printf(": unsupported format \"%s\"\n", format); + return; + } + + 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; + ri->ri_bits = bus_space_vaddr(sc->sc_iot, sc->sc_ioh); + ri->ri_hw = sc; + + printf(": %dx%d\n", ri->ri_width, ri->ri_height); + + rasops_init(ri, 160, 160); + + strlcpy(sc->sc_wsd.name, "std", sizeof(sc->sc_wsd.name)); + sc->sc_wsd.capabilities = ri->ri_caps; + sc->sc_wsd.nrows = ri->ri_rows; + sc->sc_wsd.ncols = ri->ri_cols; + sc->sc_wsd.textops = &ri->ri_ops; + sc->sc_wsd.fontwidth = ri->ri_font->fontwidth; + sc->sc_wsd.fontheight = ri->ri_font->fontheight; + + sc->sc_scrlist[0] = &sc->sc_wsd; + sc->sc_wsl.nscreens = 1; + sc->sc_wsl.screens = (const struct wsscreen_descr **)sc->sc_scrlist; + + memset(&waa, 0, sizeof(waa)); + waa.scrdata = &sc->sc_wsl; + waa.accessops = &simplefb_accessops; + waa.accesscookie = ri; + + config_found_sm(self, &waa, wsemuldisplaydevprint, + wsemuldisplaydevsubmatch); +} + +int +simplefb_wsioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) +{ + struct rasops_info *ri = v; + struct wsdisplay_fbinfo *wdf; + + switch (cmd) { + case WSDISPLAYIO_GTYPE: + *(int *)data = WSDISPLAY_TYPE_EFIFB; + return 0; + case WSDISPLAYIO_GINFO: + wdf = (struct wsdisplay_fbinfo *)data; + wdf->width = ri->ri_width; + wdf->height = ri->ri_height; + wdf->depth = ri->ri_depth; + wdf->cmsize = 0; /* color map is unavailable */ + break; + case WSDISPLAYIO_LINEBYTES: + *(u_int *)data = ri->ri_stride; + break; + case WSDISPLAYIO_SMODE: + break; + case WSDISPLAYIO_GETSUPPORTEDDEPTH: + switch (ri->ri_depth) { + case 32: + *(u_int *)data = WSDISPLAYIO_DEPTH_24_32; + break; + case 24: + *(u_int *)data = WSDISPLAYIO_DEPTH_24_24; + break; + case 16: + *(u_int *)data = WSDISPLAYIO_DEPTH_16; + break; + case 15: + *(u_int *)data = WSDISPLAYIO_DEPTH_15; + break; + default: + return -1; + } + break; + default: + return -1; + } + + return 0; +} + +paddr_t +simplefb_wsmmap(void *v, off_t off, int prot) +{ + struct rasops_info *ri = v; + struct simplefb_softc *sc = ri->ri_hw; + + if (off < 0 || off >= sc->sc_psize) + return -1; + + return sc->sc_paddr + off; +} + +int +simplefb_alloc_screen(void *v, const struct wsscreen_descr *type, + void **cookiep, int *curxp, int *curyp, long *attrp) +{ + return rasops_alloc_screen(v, cookiep, curxp, curyp, attrp); +}