diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/boot/fdt/dts/mips/beripad-de4.dts | 1 | ||||
-rw-r--r-- | sys/dev/terasic/mtl/terasic_mtl.c | 31 | ||||
-rw-r--r-- | sys/dev/terasic/mtl/terasic_mtl.h | 23 | ||||
-rw-r--r-- | sys/dev/terasic/mtl/terasic_mtl_fdt.c | 24 | ||||
-rw-r--r-- | sys/dev/terasic/mtl/terasic_mtl_nexus.c | 24 | ||||
-rw-r--r-- | sys/dev/terasic/mtl/terasic_mtl_reg.c | 17 | ||||
-rw-r--r-- | sys/dev/terasic/mtl/terasic_mtl_text.c | 4 | ||||
-rw-r--r-- | sys/dev/terasic/mtl/terasic_mtl_vt.c | 133 | ||||
-rw-r--r-- | sys/mips/beri/files.beri | 3 | ||||
-rw-r--r-- | sys/mips/conf/BERI_DE4_BASE | 3 |
10 files changed, 241 insertions, 22 deletions
diff --git a/sys/boot/fdt/dts/mips/beripad-de4.dts b/sys/boot/fdt/dts/mips/beripad-de4.dts index 82faffc..05ce0c2 100644 --- a/sys/boot/fdt/dts/mips/beripad-de4.dts +++ b/sys/boot/fdt/dts/mips/beripad-de4.dts @@ -216,6 +216,7 @@ touchscreen@70400000 { compatible = "sri-cambridge,mtl"; + panel-size = < 800 480 >; reg = <0x70400000 0x1000 0x70000000 0x177000 0x70177000 0x2000>; diff --git a/sys/dev/terasic/mtl/terasic_mtl.c b/sys/dev/terasic/mtl/terasic_mtl.c index 5305172..2a0744b 100644 --- a/sys/dev/terasic/mtl/terasic_mtl.c +++ b/sys/dev/terasic/mtl/terasic_mtl.c @@ -31,11 +31,14 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_syscons.h" + #include <sys/param.h> #include <sys/bus.h> #include <sys/condvar.h> #include <sys/conf.h> #include <sys/consio.h> /* struct vt_mode */ +#include <sys/endian.h> #include <sys/fbio.h> /* video_adapter_t */ #include <sys/kernel.h> #include <sys/lock.h> @@ -53,8 +56,8 @@ __FBSDID("$FreeBSD$"); /* * 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 +84,27 @@ terasic_mtl_attach(struct terasic_mtl_softc *sc) 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) + terasic_mtl_reg_pixel_endian_set(sc, BYTE_ORDER == BIG_ENDIAN); + 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 +117,13 @@ void 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); diff --git a/sys/dev/terasic/mtl/terasic_mtl.h b/sys/dev/terasic/mtl/terasic_mtl.h index ad77248..f03e6f0 100644 --- a/sys/dev/terasic/mtl/terasic_mtl.h +++ b/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 @@ struct terasic_mtl_softc { 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 terasic_mtl_softc { 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) @@ -106,6 +116,7 @@ struct terasic_mtl_softc { /* * Constants to help interpret various control registers. */ +#define TERASIC_MTL_BLEND_PIXEL_ENDIAN_SWAP 0x10000000 #define TERASIC_MTL_BLEND_DEFAULT_MASK 0x0f000000 #define TERASIC_MTL_BLEND_DEFAULT_SHIFT 24 #define TERASIC_MTL_BLEND_PIXEL_MASK 0x00ff0000 @@ -148,6 +159,12 @@ struct terasic_mtl_softc { #define TERASIC_MTL_TEXTFRAMEBUF_ATTR_SHIFT 8 /* + * Framebuffer constants. + */ +#define TERASIC_MTL_FB_WIDTH 800 +#define TERASIC_MTL_FB_HEIGHT 640 + +/* * Alpha-blending constants. */ #define TERASIC_MTL_ALPHA_TRANSPARENT 0 @@ -164,6 +181,8 @@ extern devclass_t terasic_mtl_devclass; /* * 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); @@ -202,6 +221,8 @@ void terasic_mtl_blend_textfg_set(struct terasic_mtl_softc *sc, uint8_t alpha); void terasic_mtl_blend_textbg_set(struct terasic_mtl_softc *sc, uint8_t alpha); +void terasic_mtl_reg_pixel_endian_set(struct terasic_mtl_softc *sc, + int endian_swap); /* * Text frame buffer I/O routines. diff --git a/sys/dev/terasic/mtl/terasic_mtl_fdt.c b/sys/dev/terasic/mtl/terasic_mtl_fdt.c index 0a9b268..e592521 100644 --- a/sys/dev/terasic/mtl/terasic_mtl_fdt.c +++ b/sys/dev/terasic/mtl/terasic_mtl_fdt.c @@ -55,6 +55,8 @@ __FBSDID("$FreeBSD$"); #include <dev/terasic/mtl/terasic_mtl.h> +#include "fb_if.h" + static int terasic_mtl_fdt_probe(device_t dev) { @@ -94,12 +96,12 @@ terasic_mtl_fdt_attach(device_t dev) goto error; } if (rman_get_start(sc->mtl_reg_res) % PAGE_SIZE != 0) { - device_printf(dev, "improper register address"); + device_printf(dev, "improper register address\n"); error = ENXIO; goto error; } if (rman_get_size(sc->mtl_reg_res) % PAGE_SIZE != 0) { - device_printf(dev, "improper register size"); + device_printf(dev, "improper register size\n"); error = ENXIO; goto error; } @@ -117,12 +119,12 @@ terasic_mtl_fdt_attach(device_t dev) goto error; } if (rman_get_start(sc->mtl_pixel_res) % PAGE_SIZE != 0) { - device_printf(dev, "improper pixel address"); + device_printf(dev, "improper pixel address\n"); error = ENXIO; goto error; } if (rman_get_size(sc->mtl_pixel_res) % PAGE_SIZE != 0) { - device_printf(dev, "improper pixel size"); + device_printf(dev, "improper pixel size\n"); error = ENXIO; goto error; } @@ -140,12 +142,12 @@ terasic_mtl_fdt_attach(device_t dev) goto error; } if (rman_get_start(sc->mtl_text_res) % PAGE_SIZE != 0) { - device_printf(dev, "improper text address"); + device_printf(dev, "improper text address\n"); error = ENXIO; goto error; } if (rman_get_size(sc->mtl_text_res) % PAGE_SIZE != 0) { - device_printf(dev, "improper text size"); + device_printf(dev, "improper text size\n"); error = ENXIO; goto error; } @@ -186,10 +188,20 @@ terasic_mtl_fdt_detach(device_t dev) 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 } }; diff --git a/sys/dev/terasic/mtl/terasic_mtl_nexus.c b/sys/dev/terasic/mtl/terasic_mtl_nexus.c index b1d13db..e88dc06 100644 --- a/sys/dev/terasic/mtl/terasic_mtl_nexus.c +++ b/sys/dev/terasic/mtl/terasic_mtl_nexus.c @@ -50,6 +50,8 @@ __FBSDID("$FreeBSD$"); #include <dev/terasic/mtl/terasic_mtl.h> +#include "fb_if.h" + static int terasic_mtl_nexus_probe(device_t dev) { @@ -76,36 +78,36 @@ terasic_mtl_nexus_attach(device_t dev) */ if (resource_long_value(device_get_name(dev), device_get_unit(dev), "reg_maddr", ®_maddr) != 0 || (reg_maddr % PAGE_SIZE != 0)) { - device_printf(dev, "improper register address"); + device_printf(dev, "improper register address\n"); return (ENXIO); } if (resource_long_value(device_get_name(dev), device_get_unit(dev), "reg_msize", ®_msize) != 0 || (reg_msize % PAGE_SIZE != 0)) { - device_printf(dev, "improper register size"); + device_printf(dev, "improper register size\n"); return (ENXIO); } if (resource_long_value(device_get_name(dev), device_get_unit(dev), "pixel_maddr", &pixel_maddr) != 0 || (pixel_maddr % PAGE_SIZE != 0)) { - device_printf(dev, "improper pixel frame buffer address"); + device_printf(dev, "improper pixel frame buffer address\n"); return (ENXIO); } if (resource_long_value(device_get_name(dev), device_get_unit(dev), "pixel_msize", &pixel_msize) != 0 || (pixel_msize % PAGE_SIZE != 0)) { - device_printf(dev, "improper pixel frame buffer size"); + device_printf(dev, "improper pixel frame buffer size\n"); return (ENXIO); } if (resource_long_value(device_get_name(dev), device_get_unit(dev), "text_maddr", &text_maddr) != 0 || (text_maddr % PAGE_SIZE != 0)) { - device_printf(dev, "improper text frame buffer address"); + device_printf(dev, "improper text frame buffer address\n"); return (ENXIO); } if (resource_long_value(device_get_name(dev), device_get_unit(dev), "text_msize", &text_msize) != 0 || (text_msize % PAGE_SIZE != 0)) { - device_printf(dev, "improper text frame buffer size"); + device_printf(dev, "improper text frame buffer size\n"); return (ENXIO); } @@ -177,10 +179,20 @@ terasic_mtl_nexus_detach(device_t dev) 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 } }; diff --git a/sys/dev/terasic/mtl/terasic_mtl_reg.c b/sys/dev/terasic/mtl/terasic_mtl_reg.c index 542bd98..e5bac61 100644 --- a/sys/dev/terasic/mtl/terasic_mtl_reg.c +++ b/sys/dev/terasic/mtl/terasic_mtl_reg.c @@ -205,6 +205,21 @@ terasic_mtl_blend_textbg_set(struct terasic_mtl_softc *sc, uint8_t alpha) } void +terasic_mtl_reg_pixel_endian_set(struct terasic_mtl_softc *sc, int endian_swap) +{ + uint32_t v; + + TERASIC_MTL_LOCK(sc); + terasic_mtl_reg_blend_get(sc, &v); + if (endian_swap) + v |= TERASIC_MTL_BLEND_PIXEL_ENDIAN_SWAP; + else + v &= ~TERASIC_MTL_BLEND_PIXEL_ENDIAN_SWAP; + terasic_mtl_reg_blend_set(sc, v); + TERASIC_MTL_UNLOCK(sc); +} + +void terasic_mtl_reg_textcursor_get(struct terasic_mtl_softc *sc, uint8_t *colp, uint8_t *rowp) { @@ -232,7 +247,7 @@ void terasic_mtl_reg_blank(struct terasic_mtl_softc *sc) { - device_printf(sc->mtl_dev, "%s: not yet", __func__); + device_printf(sc->mtl_dev, "%s: not yet\n", __func__); } void diff --git a/sys/dev/terasic/mtl/terasic_mtl_text.c b/sys/dev/terasic/mtl/terasic_mtl_text.c index 3b9377f..905e62f 100644 --- a/sys/dev/terasic/mtl/terasic_mtl_text.c +++ b/sys/dev/terasic/mtl/terasic_mtl_text.c @@ -158,6 +158,7 @@ int terasic_mtl_text_attach(struct terasic_mtl_softc *sc) { uint32_t v; + u_int offset; terasic_mtl_reg_textframebufaddr_get(sc, &v); if (v != TERASIC_MTL_TEXTFRAMEBUF_EXPECTED_ADDR) { @@ -165,6 +166,9 @@ terasic_mtl_text_attach(struct terasic_mtl_softc *sc) "address (%08x); cannot attach\n", __func__, v); return (ENXIO); } + for (offset = 0; offset < rman_get_size(sc->mtl_text_res); + offset += sizeof(uint16_t)) + bus_write_2(sc->mtl_text_res, offset, 0); sc->mtl_text_cdev = make_dev(&terasic_mtl_text_cdevsw, sc->mtl_unit, UID_ROOT, GID_WHEEL, 0400, "mtl_text%d", sc->mtl_unit); diff --git a/sys/dev/terasic/mtl/terasic_mtl_vt.c b/sys/dev/terasic/mtl/terasic_mtl_vt.c new file mode 100644 index 0000000..c25248d --- /dev/null +++ b/sys/dev/terasic/mtl/terasic_mtl_vt.c @@ -0,0 +1,133 @@ +/*- + * 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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/fbio.h> +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/rman.h> + +#include <dev/fdt/fdt_common.h> +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> + +#include <dev/terasic/mtl/terasic_mtl.h> + +#include <dev/vt/colors/vt_termcolors.h> + +/* + * Terasic Multitouch LCD (MTL) vt(4) framebuffer driver. + */ + +#include <vm/vm.h> +#include <vm/pmap.h> + +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); + + /* + * Safety belt to ensure framebuffer params are as expected. May be + * removed when we have full confidence in fdt / hints params. + */ + if (info->fb_width != TERASIC_MTL_FB_WIDTH || + info->fb_height != TERASIC_MTL_FB_HEIGHT || + info->fb_stride != 3200 || + info->fb_bpp != 32 || info->fb_depth != 32) { + device_printf(sc->mtl_dev, + "rejecting invalid panel params width=%u height=%u\n", + (unsigned)info->fb_width, (unsigned)info->fb_height); + return (EINVAL); + } + + 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); + } + 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); diff --git a/sys/mips/beri/files.beri b/sys/mips/beri/files.beri index ffd70fe..26c94ff 100644 --- a/sys/mips/beri/files.beri +++ b/sys/mips/beri/files.beri @@ -16,8 +16,9 @@ dev/terasic/mtl/terasic_mtl_fdt.c optional terasic_mtl fdt dev/terasic/mtl/terasic_mtl_nexus.c optional terasic_mtl dev/terasic/mtl/terasic_mtl_pixel.c optional terasic_mtl dev/terasic/mtl/terasic_mtl_reg.c optional terasic_mtl -dev/terasic/mtl/terasic_mtl_syscons.c optional terasic_mtl +dev/terasic/mtl/terasic_mtl_syscons.c optional terasic_mtl sc dev/terasic/mtl/terasic_mtl_text.c optional terasic_mtl +dev/terasic/mtl/terasic_mtl_vt.c optional terasic_mtl vt mips/beri/beri_machdep.c standard mips/beri/beri_pic.c optional fdt mips/beri/beri_simplebus.c optional fdt diff --git a/sys/mips/conf/BERI_DE4_BASE b/sys/mips/conf/BERI_DE4_BASE index d24a41f..84adf79 100644 --- a/sys/mips/conf/BERI_DE4_BASE +++ b/sys/mips/conf/BERI_DE4_BASE @@ -33,7 +33,8 @@ device cfi device cfid options CFI_SUPPORT_STRATAFLASH options ATSE_CFI_HACK -device sc +device vt +device kbdmux device uart |