From owner-svn-src-head@FreeBSD.ORG Tue Aug 5 18:19:52 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 74C6C885 for ; Tue, 5 Aug 2014 18:19:52 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 5735121E6 for ; Tue, 5 Aug 2014 18:19:52 +0000 (UTC) Received: from nwhitehorn (uid 1171) (envelope-from nwhitehorn@FreeBSD.org) id 529c by svn.freebsd.org (DragonFly Mail Agent v0.9+); Tue, 05 Aug 2014 18:19:52 +0000 From: Nathan Whitehorn Date: Tue, 5 Aug 2014 18:19:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r269601 - in head/sys: conf dev/fb X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <53e12048.529c.76a204bd@svn.freebsd.org> X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 05 Aug 2014 18:19:52 -0000 Author: nwhitehorn Date: Tue Aug 5 18:19:51 2014 New Revision: 269601 URL: http://svnweb.freebsd.org/changeset/base/269601 Log: Add a simple unaccelerated vt(4) framebuffer driver for Sun framebuffers handled by creator(4) (Sun Creator 3D, Elite 3D, etc.). This provides vt(4) consoles on all devices currently supported by syscons on sparc64. The driver should also be easily adaptable to support newer Sun framebuffers such as the XVR-500 and higher. Many thanks to dumbbell@ (Jean-Sebastien Pedron) for testing this remotely during development. Added: head/sys/dev/fb/creator_vt.c (contents, props changed) Modified: head/sys/conf/files.sparc64 Modified: head/sys/conf/files.sparc64 ============================================================================== --- head/sys/conf/files.sparc64 Tue Aug 5 18:09:39 2014 (r269600) +++ head/sys/conf/files.sparc64 Tue Aug 5 18:19:51 2014 (r269601) @@ -35,6 +35,7 @@ dev/atkbdc/psm.c optional psm atkbdc dev/auxio/auxio.c optional auxio sbus | auxio ebus dev/esp/esp_sbus.c optional esp sbus dev/fb/creator.c optional creator sc +dev/fb/creator_vt.c optional creator vt dev/fb/fb.c optional sc dev/fb/gallant12x22.c optional sc dev/fb/machfb.c optional machfb sc Added: head/sys/dev/fb/creator_vt.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/fb/creator_vt.c Tue Aug 5 18:19:51 2014 (r269601) @@ -0,0 +1,220 @@ +/*- + * Copyright (c) 2014 Nathan Whitehorn + * All rights reserved. + * + * 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 "creatorreg.h" + +static vd_probe_t creatorfb_probe; +static vd_init_t creatorfb_init; +static vd_blank_t creatorfb_blank; +static vd_bitbltchr_t creatorfb_bitbltchr; + +static const struct vt_driver vt_creatorfb_driver = { + .vd_name = "creatorfb", + .vd_probe = creatorfb_probe, + .vd_init = creatorfb_init, + .vd_blank = creatorfb_blank, + .vd_bitbltchr = creatorfb_bitbltchr, + .vd_maskbitbltchr = creatorfb_bitbltchr, + .vd_fb_ioctl = vt_fb_ioctl, + .vd_fb_mmap = vt_fb_mmap, + .vd_priority = VD_PRIORITY_SPECIFIC +}; + +struct creatorfb_softc { + struct fb_info fb; + struct bus_space_tag memt[1]; + bus_space_handle_t memh; +}; + +static struct creatorfb_softc creatorfb_conssoftc; +VT_DRIVER_DECLARE(vt_creatorfb, vt_creatorfb_driver); + +static int +creatorfb_probe(struct vt_device *vd) +{ + phandle_t chosen, node; + ihandle_t stdout; + char type[64], name[64]; + + chosen = OF_finddevice("/chosen"); + OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)); + node = OF_instance_to_package(stdout); + if (node == -1) { + /* + * The "/chosen/stdout" does not exist try + * using "screen" directly. + */ + node = OF_finddevice("screen"); + } + OF_getprop(node, "device_type", type, sizeof(type)); + if (strcmp(type, "display") != 0) + return (CN_DEAD); + + OF_getprop(node, "name", name, sizeof(name)); + if (strcmp(name, "SUNW,ffb") != 0 && strcmp(name, "SUNW,afb") != 0) + return (CN_DEAD); + + /* Looks OK... */ + return (CN_INTERNAL); +} + +static int +creatorfb_init(struct vt_device *vd) +{ + struct creatorfb_softc *sc; + phandle_t chosen; + phandle_t node; + ihandle_t handle; + uint32_t height, width; + char type[64], name[64]; + bus_addr_t phys; + int space; + + /* Initialize softc */ + vd->vd_softc = sc = &creatorfb_conssoftc; + + chosen = OF_finddevice("/chosen"); + OF_getprop(chosen, "stdout", &handle, sizeof(ihandle_t)); + node = OF_instance_to_package(handle); + if (node == -1) { + /* + * The "/chosen/stdout" does not exist try + * using "screen" directly. + */ + node = OF_finddevice("screen"); + handle = OF_open("screen"); + } + OF_getprop(node, "device_type", type, sizeof(type)); + if (strcmp(type, "display") != 0) + return (CN_DEAD); + + OF_getprop(node, "name", name, sizeof(name)); + if (strcmp(name, "SUNW,ffb") != 0 && strcmp(name, "SUNW,afb") != 0) + return (CN_DEAD); + + /* Make sure we have needed properties */ + if (OF_getproplen(node, "height") != sizeof(height) || + OF_getproplen(node, "width") != sizeof(width)) + return (CN_DEAD); + + OF_getprop(node, "height", &height, sizeof(height)); + OF_getprop(node, "width", &width, sizeof(width)); + + sc->fb.fb_height = height; + sc->fb.fb_width = width; + sc->fb.fb_bpp = sc->fb.fb_depth = 32; + sc->fb.fb_stride = 8192; /* Fixed */ + sc->fb.fb_size = sc->fb.fb_height * sc->fb.fb_stride; + + /* Map linear framebuffer */ + if (OF_decode_addr(node, FFB_DFB24, &space, &phys) != 0) + return (CN_DEAD); + sc->fb.fb_pbase = phys; + sc->memh = sparc64_fake_bustag(space, phys, &sc->memt[0]); + + /* 32-bit VGA palette */ + vt_generate_vga_palette(sc->fb.fb_cmap, COLOR_FORMAT_RGB, + 255, 16, 255, 8, 255, 0); + + vt_fb_init(vd); + + return (CN_INTERNAL); +} + +static void +creatorfb_blank(struct vt_device *vd, term_color_t color) +{ + struct creatorfb_softc *sc; + uint32_t c; + int i; + + sc = vd->vd_softc; + c = sc->fb.fb_cmap[color]; + + for (i = 0; i < sc->fb.fb_height; i++) + bus_space_set_region_4(sc->memt, sc->memh, i*sc->fb.fb_stride, + c, sc->fb.fb_width); +} + +static void +creatorfb_bitbltchr(struct vt_device *vd, const uint8_t *src, + const uint8_t *mask, int bpl, vt_axis_t top, vt_axis_t left, + unsigned int width, unsigned int height, term_color_t fg, term_color_t bg) +{ + struct creatorfb_softc *sc = vd->vd_softc; + u_long line; + uint32_t fgc, bgc; + int c; + uint8_t b, m; + + fgc = sc->fb.fb_cmap[fg]; + bgc = sc->fb.fb_cmap[bg]; + b = m = 0; + + /* Don't try to put off screen pixels */ + if (((left + width) > vd->vd_width) || ((top + height) > + vd->vd_height)) + return; + + line = (sc->fb.fb_stride * top) + 4*left; + for (; height > 0; height--) { + for (c = 0; c < width; c++) { + if (c % 8 == 0) + b = *src++; + else + b <<= 1; + if (mask != NULL) { + if (c % 8 == 0) + m = *mask++; + else + m <<= 1; + /* Skip pixel write if mask not set. */ + if ((m & 0x80) == 0) + continue; + } + bus_space_write_4(sc->memt, sc->memh, line + 4*c, + (b & 0x80) ? fgc : bgc); + } + line += sc->fb.fb_stride; + } +} +