diff options
author | 2020-10-01 17:28:14 +0000 | |
---|---|---|
committer | 2020-10-01 17:28:14 +0000 | |
commit | 2b67eb97db8c58ae440042816bffbf5d6715a9ca (patch) | |
tree | f1f7bbc7ef70e52ea6aa1f69c03f04984017f9c4 | |
parent | Attach on Intel 400-series chipsets. (diff) | |
download | wireguard-openbsd-2b67eb97db8c58ae440042816bffbf5d6715a9ca.tar.xz wireguard-openbsd-2b67eb97db8c58ae440042816bffbf5d6715a9ca.zip |
Add astfb(4), a driver for the framebuffer of the Aspeed BMC found on
many POWER8 and POWER9 systems.
-rw-r--r-- | sys/arch/powerpc64/conf/GENERIC | 8 | ||||
-rw-r--r-- | sys/arch/powerpc64/conf/files.powerpc64 | 6 | ||||
-rw-r--r-- | sys/arch/powerpc64/dev/astfb.c | 236 | ||||
-rw-r--r-- | sys/dev/wscons/wsconsio.h | 3 |
4 files changed, 250 insertions, 3 deletions
diff --git a/sys/arch/powerpc64/conf/GENERIC b/sys/arch/powerpc64/conf/GENERIC index 6749f3f9571..c0e00acab8e 100644 --- a/sys/arch/powerpc64/conf/GENERIC +++ b/sys/arch/powerpc64/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.18 2020/09/05 13:55:45 kettenis Exp $ +# $OpenBSD: GENERIC,v 1.19 2020/10/01 17:28:14 kettenis Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -30,7 +30,13 @@ xics* at fdt? xicp* at fdt? xive* at fdt? +option WSDISPLAY_COMPAT_USL +option WSDISPLAY_COMPAT_RAWKBD +option WSDISPLAY_DEFAULTSCREENS=6 + ahci* at pci? +astfb* at pci? +wsdisplay* at astfb? bge* at pci? mpii* at pci? nvme* at pci? diff --git a/sys/arch/powerpc64/conf/files.powerpc64 b/sys/arch/powerpc64/conf/files.powerpc64 index 2158a027749..bad8763de8c 100644 --- a/sys/arch/powerpc64/conf/files.powerpc64 +++ b/sys/arch/powerpc64/conf/files.powerpc64 @@ -1,4 +1,4 @@ -# $OpenBSD: files.powerpc64,v 1.23 2020/08/23 19:18:42 kettenis Exp $ +# $OpenBSD: files.powerpc64,v 1.24 2020/10/01 17:28:14 kettenis Exp $ maxpartitions 16 maxusers 2 8 128 @@ -102,6 +102,10 @@ device xive attach xive at fdt file arch/powerpc64/dev/xive.c xive +device astfb: wsemuldisplaydev, rasops32 +attach astfb at pci +file arch/powerpc64/dev/astfb.c astfb + # Machine-independent HID support include "dev/hid/files.hid" diff --git a/sys/arch/powerpc64/dev/astfb.c b/sys/arch/powerpc64/dev/astfb.c new file mode 100644 index 00000000000..32a9d3d0fc1 --- /dev/null +++ b/sys/arch/powerpc64/dev/astfb.c @@ -0,0 +1,236 @@ +/* $OpenBSD: astfb.c,v 1.1 2020/10/01 17:28:14 kettenis Exp $ */ + +/* + * Copyright (c) 2020 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/device.h> +#include <sys/systm.h> + +#include <machine/bus.h> + +#include <dev/ofw/openfirm.h> + +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pcidevs.h> + +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/wsdisplayvar.h> + +#include <dev/rasops/rasops.h> + +#define ASTFB_PCI_FB 0x10 + +struct astfb_softc { + struct device sc_dev; + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + + bus_addr_t sc_fbaddr; + bus_size_t sc_fbsize; + + struct rasops_info sc_ri; + struct wsscreen_descr sc_wsd; + struct wsscreen_list sc_wsl; + struct wsscreen_descr *sc_scrlist[1]; +}; + +int astfb_wsioctl(void *, u_long, caddr_t, int, struct proc *); +paddr_t astfb_wsmmap(void *, off_t, int); +int astfb_alloc_screen(void *, const struct wsscreen_descr *, + void **, int *, int *, uint32_t *); + +struct wsdisplay_accessops astfb_accessops = { + .ioctl = astfb_wsioctl, + .mmap = astfb_wsmmap, + .alloc_screen = astfb_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, + .scrollback = rasops_scrollback +}; + +int astfb_match(struct device *, void *, void *); +void astfb_attach(struct device *, struct device *, void *); + +struct cfattach astfb_ca = { + sizeof(struct astfb_softc), astfb_match, astfb_attach +}; + +struct cfdriver astfb_cd = { + NULL, "astfb", DV_DULL +}; + +int +astfb_match(struct device *parent, void *cf, void *aux) +{ + struct pci_attach_args *pa = aux; + + if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ASPEED && + PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ASPEED_AST2000 && + PCITAG_NODE(pa->pa_tag) != 0) + return 1; + + return 0; +} + +void +astfb_attach(struct device *parent, struct device *self, void *aux) +{ + struct astfb_softc *sc = (struct astfb_softc *)self; + struct pci_attach_args *pa = aux; + struct rasops_info *ri = &sc->sc_ri; + struct wsemuldisplaydev_attach_args waa; + int node = PCITAG_NODE(pa->pa_tag); + uint32_t addr[5]; + + if (OF_getpropintarray(node, "assigned-addresses", addr, + sizeof(addr)) < sizeof(addr)) { + printf(": no framebuffer\n"); + return; + } + + sc->sc_fbaddr = (bus_addr_t)addr[1] << 32 | addr[2]; + sc->sc_fbsize = (bus_size_t)addr[3] << 32 | addr[4]; + + sc->sc_iot = pa->pa_memt; + if (bus_space_map(sc->sc_iot, sc->sc_fbaddr, sc->sc_fbsize, + BUS_SPACE_MAP_LINEAR, &sc->sc_ioh)) { + printf(": can't map framebuffer\n"); + return; + } + + printf("\n"); + + ri->ri_bits = bus_space_vaddr(sc->sc_iot, sc->sc_ioh); + ri->ri_hw = sc; + + ri->ri_width = OF_getpropint(node, "width", 0); + ri->ri_height = OF_getpropint(node, "height", 0); + ri->ri_depth = OF_getpropint(node, "depth", 0); + ri->ri_stride = ri->ri_width * ((ri->ri_depth + 7) / 8); + ri->ri_flg = RI_CENTER | RI_CLEAR | RI_FULLCLEAR | RI_WRONLY; + + switch (ri->ri_depth) { + case 32: + ri->ri_rnum = 8; + ri->ri_rpos = 8; + ri->ri_gnum = 8; + ri->ri_gpos = 16; + ri->ri_bnum = 8; + ri->ri_bpos = 24; + break; + case 16: + ri->ri_rnum = 5; + ri->ri_rpos = 0; + ri->ri_gnum = 6; + ri->ri_gpos = 6; + ri->ri_bnum = 5; + ri->ri_bpos = 11; + break; + } + + printf("%s: %dx%d, %dbpp\n", sc->sc_dev.dv_xname, + ri->ri_width, ri->ri_height, ri->ri_depth); + + ri->ri_flg |= RI_VCONS; + 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 = &astfb_accessops; + waa.accesscookie = ri; + waa.console = 0; + + config_found_sm(self, &waa, wsemuldisplaydevprint, + wsemuldisplaydevsubmatch); +} + +int +astfb_wsioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p) +{ + struct rasops_info *ri = v; + struct wsdisplay_fbinfo *wdf; + + switch (cmd) { + case WSDISPLAYIO_GTYPE: + *(u_int *)data = WSDISPLAY_TYPE_ASTFB; + break; + case WSDISPLAYIO_GINFO: + wdf = (void *)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 16: + *(u_int *)data = WSDISPLAYIO_DEPTH_16; + break; + default: + return -1; + } + break; + default: + return -1; + } + + return 0; +} + +paddr_t +astfb_wsmmap(void *v, off_t off, int prot) +{ + struct rasops_info *ri = v; + struct astfb_softc *sc = ri->ri_hw; + + if (off < 0 || off >= sc->sc_fbaddr) + return -1; + + return (bus_space_mmap(sc->sc_iot, sc->sc_fbaddr, + off, prot, BUS_SPACE_MAP_LINEAR)); +} + +int +astfb_alloc_screen(void *v, const struct wsscreen_descr *type, + void **cookiep, int *curxp, int *curyp, uint32_t *attrp) +{ + return rasops_alloc_screen(v, cookiep, curxp, curyp, attrp); +} diff --git a/sys/dev/wscons/wsconsio.h b/sys/dev/wscons/wsconsio.h index 6b72eb9c344..32ef4116521 100644 --- a/sys/dev/wscons/wsconsio.h +++ b/sys/dev/wscons/wsconsio.h @@ -1,4 +1,4 @@ -/* $OpenBSD: wsconsio.h,v 1.94 2020/03/22 07:59:59 anton Exp $ */ +/* $OpenBSD: wsconsio.h,v 1.95 2020/10/01 17:28:14 kettenis Exp $ */ /* $NetBSD: wsconsio.h,v 1.74 2005/04/28 07:15:44 martin Exp $ */ /* @@ -439,6 +439,7 @@ struct wsmouse_parameters { #define WSDISPLAY_TYPE_RADEONDRM 70 /* ATI Radeon KMS framebuffer */ #define WSDISPLAY_TYPE_EFIFB 71 /* EFI framebuffer */ #define WSDISPLAY_TYPE_RKDRM 72 /* Rockchip KMS framebuffer */ +#define WSDISPLAY_TYPE_ASTFB 73 /* AST framebuffer */ /* Basic display information. Not applicable to all display types. */ struct wsdisplay_fbinfo { |