Index: sys/dev/terasic/mtl/terasic_mtl.h =================================================================== --- sys/dev/terasic/mtl/terasic_mtl.h +++ sys/dev/terasic/mtl/terasic_mtl.h @@ -33,13 +33,17 @@ #ifndef _DEV_TERASIC_MTL_H_ #define _DEV_TERASIC_MTL_H_ +#include "opt_syscons.h" + struct terasic_mtl_softc { +#if defined(DEV_SC) /* * syscons requires that its video_adapter_t be at the front of the * softc, so place syscons fields first, which we otherwise would * probably not do. */ video_adapter_t mtl_va; +#endif /* * Bus-related fields. @@ -62,7 +66,8 @@ int mtl_reg_rid; /* - * Graphics frame buffer device -- mappable from userspace. + * Graphics frame buffer device -- mappable from userspace, and used + * by the vt framebuffer interface. */ struct cdev *mtl_pixel_cdev; struct resource *mtl_pixel_res; @@ -76,6 +81,11 @@ struct resource *mtl_text_res; int mtl_text_rid; uint16_t *mtl_text_soft; + + /* + * Framebuffer hookup for vt(4). + */ + struct fb_info mtl_fb_info; }; #define TERASIC_MTL_LOCK(sc) mtx_lock(&(sc)->mtl_lock) @@ -164,6 +174,8 @@ /* * Sub-driver setup routines. */ +int terasic_mtl_fbd_attach(struct terasic_mtl_softc *sc); +void terasic_mtl_fbd_detach(struct terasic_mtl_softc *sc); int terasic_mtl_pixel_attach(struct terasic_mtl_softc *sc); void terasic_mtl_pixel_detach(struct terasic_mtl_softc *sc); int terasic_mtl_reg_attach(struct terasic_mtl_softc *sc); Index: sys/dev/terasic/mtl/terasic_mtl.c =================================================================== --- sys/dev/terasic/mtl/terasic_mtl.c +++ sys/dev/terasic/mtl/terasic_mtl.c @@ -31,6 +31,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_syscons.h" + #include #include #include @@ -53,8 +55,8 @@ /* * Device driver for the Terasic Multitouch LCD (MTL). Three separate * sub-drivers that support, respectively, access to device control registers, - * the pixel frame buffer, and the text frame buffer. The last of these is - * also hooked up to syscons. + * the pixel frame buffer, and the text frame buffer. The pixel frame buffer + * is hooked up to vt(4), and the text frame buffer to syscons(4). * * Eventually, the frame buffer control registers and touch screen input FIFO * will end up being separate sub-drivers as well. @@ -81,16 +83,26 @@ if (error) goto error; /* - * XXXRW: Once we've attached syscons, we can't detach it, so do it - * last. + * XXXRW: Once we've attached syscons or vt, we can't detach it, so do + * it last. */ +#if defined(DEV_VT) + error = terasic_mtl_fbd_attach(sc); + if (error) + goto error; + terasic_mtl_blend_pixel_set(sc, TERASIC_MTL_ALPHA_OPAQUE); + terasic_mtl_blend_textfg_set(sc, TERASIC_MTL_ALPHA_TRANSPARENT); + terasic_mtl_blend_textbg_set(sc, TERASIC_MTL_ALPHA_TRANSPARENT); +#endif +#if defined(DEV_SC) error = terasic_mtl_syscons_attach(sc); if (error) goto error; - terasic_mtl_blend_default_set(sc, TERASIC_MTL_COLOR_BLACK); terasic_mtl_blend_pixel_set(sc, TERASIC_MTL_ALPHA_TRANSPARENT); terasic_mtl_blend_textfg_set(sc, TERASIC_MTL_ALPHA_OPAQUE); terasic_mtl_blend_textbg_set(sc, TERASIC_MTL_ALPHA_OPAQUE); +#endif + terasic_mtl_blend_default_set(sc, TERASIC_MTL_COLOR_BLACK); return (0); error: terasic_mtl_text_detach(sc); @@ -103,8 +115,13 @@ terasic_mtl_detach(struct terasic_mtl_softc *sc) { - /* XXXRW: syscons can't detach, but we try anyway, only to panic. */ + /* XXXRW: syscons and vt can't detach, but try anyway, only to panic. */ +#if defined(DEV_SC) terasic_mtl_syscons_detach(sc); +#endif +#if defined(DEV_VT) + terasic_mtl_fbd_detach(sc); +#endif /* All other aspects of the driver can detach just fine. */ terasic_mtl_text_detach(sc); Index: sys/dev/terasic/mtl/terasic_mtl_fdt.c =================================================================== --- sys/dev/terasic/mtl/terasic_mtl_fdt.c +++ sys/dev/terasic/mtl/terasic_mtl_fdt.c @@ -55,6 +55,8 @@ #include +#include "fb_if.h" + static int terasic_mtl_fdt_probe(device_t dev) { @@ -186,10 +188,20 @@ return (0); } +static struct fb_info * +terasic_mtl_fb_getinfo(device_t dev) +{ + struct terasic_mtl_softc *sc; + + sc = device_get_softc(dev); + return (&sc->mtl_fb_info); +} + static device_method_t terasic_mtl_fdt_methods[] = { DEVMETHOD(device_probe, terasic_mtl_fdt_probe), DEVMETHOD(device_attach, terasic_mtl_fdt_attach), DEVMETHOD(device_detach, terasic_mtl_fdt_detach), + DEVMETHOD(fb_getinfo, terasic_mtl_fb_getinfo), { 0, 0 } }; Index: sys/dev/terasic/mtl/terasic_mtl_nexus.c =================================================================== --- sys/dev/terasic/mtl/terasic_mtl_nexus.c +++ sys/dev/terasic/mtl/terasic_mtl_nexus.c @@ -50,6 +50,8 @@ #include +#include "fb_if.h" + static int terasic_mtl_nexus_probe(device_t dev) { @@ -177,10 +179,20 @@ return (0); } +static struct fb_info * +terasic_mtl_fb_getinfo(device_t dev) +{ + struct terasic_mtl_softc *sc; + + sc = device_get_softc(dev); + return (&sc->mtl_fb_info); +} + static device_method_t terasic_mtl_nexus_methods[] = { DEVMETHOD(device_probe, terasic_mtl_nexus_probe), DEVMETHOD(device_attach, terasic_mtl_nexus_attach), DEVMETHOD(device_detach, terasic_mtl_nexus_detach), + DEVMETHOD(fb_getinfo, terasic_mtl_fb_getinfo), { 0, 0 } }; Index: sys/dev/terasic/mtl/terasic_mtl_vt.c =================================================================== --- /dev/null +++ sys/dev/terasic/mtl/terasic_mtl_vt.c @@ -0,0 +1,128 @@ +/*- + * Copyright (c) 2014 Ed Maste + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +/* + * Terasic Multitouch LCD (MTL) vt(4) framebuffer driver. + */ + +#include +#include + +static int +terasic_mtl_fbd_panel_info(struct terasic_mtl_softc *sc, struct fb_info *info) +{ + phandle_t node; + pcell_t dts_value[2]; + int len; + + if ((node = ofw_bus_get_node(sc->mtl_dev)) == -1) + return (ENXIO); + + /* panel size */ + if ((len = OF_getproplen(node, "panel-size")) != sizeof(dts_value)) + return (ENXIO); + OF_getencprop(node, "panel-size", dts_value, len); + info->fb_width = dts_value[0]; + info->fb_height = dts_value[1]; + info->fb_bpp = info->fb_depth = 32; + info->fb_stride = info->fb_width * (info->fb_depth / 8); +#if 1 + if (info->fb_width != 800 || info->fb_height != 480 || + info->fb_stride != 3200 || + info->fb_bpp != 32 || info->fb_depth != 32) { + printf("w=%u h=%u\n", (unsigned)info->fb_width, (unsigned)info->fb_height); + return (EINVAL); + } +#endif + return (0); +} + +int +terasic_mtl_fbd_attach(struct terasic_mtl_softc *sc) +{ + struct fb_info *info; + device_t fbd; + + info = &sc->mtl_fb_info; + info->fb_name = device_get_nameunit(sc->mtl_dev); + info->fb_pbase = rman_get_start(sc->mtl_pixel_res); + info->fb_size = rman_get_size(sc->mtl_pixel_res); + info->fb_vbase = (intptr_t)pmap_mapdev(info->fb_pbase, info->fb_size); + if (terasic_mtl_fbd_panel_info(sc, info) != 0) { + device_printf(sc->mtl_dev, "using default panel params\n"); + info->fb_bpp = info->fb_depth = 32; + info->fb_width = 800; + info->fb_height = 480; + info->fb_stride = info->fb_width * (info->fb_depth / 8); + } + + fbd = device_add_child(sc->mtl_dev, "fbd", + device_get_unit(sc->mtl_dev)); + if (fbd == NULL) { + device_printf(sc->mtl_dev, "Failed to attach fbd child\n"); + return (ENXIO); + } + if (device_probe_and_attach(fbd) != 0) { + device_printf(sc->mtl_dev, + "Failed to attach fbd device\n"); + return (ENXIO); + } + (void)vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, + 0xff, 8, 0xff, 16, 0xff, 24); + return (0); +} + +void +terasic_mtl_fbd_detach(struct terasic_mtl_softc *sc) +{ + panic("%s: detach not implemented", __func__); +} + +extern device_t fbd_driver; +extern devclass_t fbd_devclass; +DRIVER_MODULE(fbd, terasic_mtl, fbd_driver, fbd_devclass, 0, 0);