1269601Snwhitehorn/*- 2269601Snwhitehorn * Copyright (c) 2014 Nathan Whitehorn 3269601Snwhitehorn * All rights reserved. 4269601Snwhitehorn * 5269601Snwhitehorn * Redistribution and use in source and binary forms, with or without 6269601Snwhitehorn * modification, are permitted provided that the following conditions 7269601Snwhitehorn * are met: 8269601Snwhitehorn * 1. Redistributions of source code must retain the above copyright 9269601Snwhitehorn * notice, this list of conditions and the following disclaimer. 10269601Snwhitehorn * 2. Redistributions in binary form must reproduce the above copyright 11269601Snwhitehorn * notice, this list of conditions and the following disclaimer in the 12269601Snwhitehorn * documentation and/or other materials provided with the distribution. 13269601Snwhitehorn * 14269601Snwhitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15269601Snwhitehorn * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16269601Snwhitehorn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17269601Snwhitehorn * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18269601Snwhitehorn * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19269601Snwhitehorn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20269601Snwhitehorn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21269601Snwhitehorn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22269601Snwhitehorn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23269601Snwhitehorn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24269601Snwhitehorn * SUCH DAMAGE. 25269601Snwhitehorn */ 26269601Snwhitehorn 27269601Snwhitehorn#include <sys/cdefs.h> 28269601Snwhitehorn__FBSDID("$FreeBSD: releng/10.2/sys/dev/fb/creator_vt.c 271128 2014-09-04 20:18:08Z emaste $"); 29269601Snwhitehorn 30269601Snwhitehorn#include <sys/param.h> 31269601Snwhitehorn#include <sys/kernel.h> 32269601Snwhitehorn#include <sys/systm.h> 33269601Snwhitehorn#include <sys/fbio.h> 34269601Snwhitehorn 35269601Snwhitehorn#include <dev/vt/vt.h> 36269601Snwhitehorn#include <dev/vt/hw/fb/vt_fb.h> 37269601Snwhitehorn#include <dev/vt/colors/vt_termcolors.h> 38269601Snwhitehorn 39269601Snwhitehorn#include <machine/bus.h> 40269601Snwhitehorn#include <machine/bus_private.h> 41269601Snwhitehorn 42269601Snwhitehorn#include <dev/ofw/openfirm.h> 43269601Snwhitehorn#include "creatorreg.h" 44269601Snwhitehorn 45269601Snwhitehornstatic vd_probe_t creatorfb_probe; 46269601Snwhitehornstatic vd_init_t creatorfb_init; 47269601Snwhitehornstatic vd_blank_t creatorfb_blank; 48271128Semastestatic vd_bitblt_text_t creatorfb_bitblt_text; 49271128Semastestatic vd_bitblt_bmp_t creatorfb_bitblt_bitmap; 50269601Snwhitehorn 51269601Snwhitehornstatic const struct vt_driver vt_creatorfb_driver = { 52269601Snwhitehorn .vd_name = "creatorfb", 53269601Snwhitehorn .vd_probe = creatorfb_probe, 54269601Snwhitehorn .vd_init = creatorfb_init, 55269601Snwhitehorn .vd_blank = creatorfb_blank, 56271128Semaste .vd_bitblt_text = creatorfb_bitblt_text, 57271128Semaste .vd_bitblt_bmp = creatorfb_bitblt_bitmap, 58269601Snwhitehorn .vd_fb_ioctl = vt_fb_ioctl, 59269601Snwhitehorn .vd_fb_mmap = vt_fb_mmap, 60269601Snwhitehorn .vd_priority = VD_PRIORITY_SPECIFIC 61269601Snwhitehorn}; 62269601Snwhitehorn 63269601Snwhitehornstruct creatorfb_softc { 64269601Snwhitehorn struct fb_info fb; 65269601Snwhitehorn struct bus_space_tag memt[1]; 66269601Snwhitehorn bus_space_handle_t memh; 67269601Snwhitehorn}; 68269601Snwhitehorn 69269601Snwhitehornstatic struct creatorfb_softc creatorfb_conssoftc; 70269601SnwhitehornVT_DRIVER_DECLARE(vt_creatorfb, vt_creatorfb_driver); 71269601Snwhitehorn 72269601Snwhitehornstatic int 73269601Snwhitehorncreatorfb_probe(struct vt_device *vd) 74269601Snwhitehorn{ 75269601Snwhitehorn phandle_t chosen, node; 76269601Snwhitehorn ihandle_t stdout; 77269601Snwhitehorn char type[64], name[64]; 78269601Snwhitehorn 79269601Snwhitehorn chosen = OF_finddevice("/chosen"); 80269601Snwhitehorn OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)); 81269601Snwhitehorn node = OF_instance_to_package(stdout); 82269601Snwhitehorn if (node == -1) { 83269601Snwhitehorn /* 84269601Snwhitehorn * The "/chosen/stdout" does not exist try 85269601Snwhitehorn * using "screen" directly. 86269601Snwhitehorn */ 87269601Snwhitehorn node = OF_finddevice("screen"); 88269601Snwhitehorn } 89269601Snwhitehorn OF_getprop(node, "device_type", type, sizeof(type)); 90269601Snwhitehorn if (strcmp(type, "display") != 0) 91269601Snwhitehorn return (CN_DEAD); 92269601Snwhitehorn 93269601Snwhitehorn OF_getprop(node, "name", name, sizeof(name)); 94269601Snwhitehorn if (strcmp(name, "SUNW,ffb") != 0 && strcmp(name, "SUNW,afb") != 0) 95269601Snwhitehorn return (CN_DEAD); 96269601Snwhitehorn 97269601Snwhitehorn /* Looks OK... */ 98269601Snwhitehorn return (CN_INTERNAL); 99269601Snwhitehorn} 100269601Snwhitehorn 101269601Snwhitehornstatic int 102269601Snwhitehorncreatorfb_init(struct vt_device *vd) 103269601Snwhitehorn{ 104269601Snwhitehorn struct creatorfb_softc *sc; 105269601Snwhitehorn phandle_t chosen; 106269601Snwhitehorn phandle_t node; 107269601Snwhitehorn ihandle_t handle; 108269601Snwhitehorn uint32_t height, width; 109269601Snwhitehorn char type[64], name[64]; 110269601Snwhitehorn bus_addr_t phys; 111269601Snwhitehorn int space; 112269601Snwhitehorn 113269601Snwhitehorn /* Initialize softc */ 114269601Snwhitehorn vd->vd_softc = sc = &creatorfb_conssoftc; 115269601Snwhitehorn 116269601Snwhitehorn chosen = OF_finddevice("/chosen"); 117269601Snwhitehorn OF_getprop(chosen, "stdout", &handle, sizeof(ihandle_t)); 118269601Snwhitehorn node = OF_instance_to_package(handle); 119269601Snwhitehorn if (node == -1) { 120269601Snwhitehorn /* 121269601Snwhitehorn * The "/chosen/stdout" does not exist try 122269601Snwhitehorn * using "screen" directly. 123269601Snwhitehorn */ 124269601Snwhitehorn node = OF_finddevice("screen"); 125269601Snwhitehorn handle = OF_open("screen"); 126269601Snwhitehorn } 127269601Snwhitehorn OF_getprop(node, "device_type", type, sizeof(type)); 128269601Snwhitehorn if (strcmp(type, "display") != 0) 129269601Snwhitehorn return (CN_DEAD); 130269601Snwhitehorn 131269601Snwhitehorn OF_getprop(node, "name", name, sizeof(name)); 132269601Snwhitehorn if (strcmp(name, "SUNW,ffb") != 0 && strcmp(name, "SUNW,afb") != 0) 133269601Snwhitehorn return (CN_DEAD); 134269601Snwhitehorn 135269601Snwhitehorn /* Make sure we have needed properties */ 136269601Snwhitehorn if (OF_getproplen(node, "height") != sizeof(height) || 137269601Snwhitehorn OF_getproplen(node, "width") != sizeof(width)) 138269601Snwhitehorn return (CN_DEAD); 139269601Snwhitehorn 140269601Snwhitehorn OF_getprop(node, "height", &height, sizeof(height)); 141269601Snwhitehorn OF_getprop(node, "width", &width, sizeof(width)); 142269601Snwhitehorn 143269601Snwhitehorn sc->fb.fb_height = height; 144269601Snwhitehorn sc->fb.fb_width = width; 145269601Snwhitehorn sc->fb.fb_bpp = sc->fb.fb_depth = 32; 146269601Snwhitehorn sc->fb.fb_stride = 8192; /* Fixed */ 147269601Snwhitehorn sc->fb.fb_size = sc->fb.fb_height * sc->fb.fb_stride; 148269601Snwhitehorn 149269601Snwhitehorn /* Map linear framebuffer */ 150269601Snwhitehorn if (OF_decode_addr(node, FFB_DFB24, &space, &phys) != 0) 151269601Snwhitehorn return (CN_DEAD); 152269601Snwhitehorn sc->fb.fb_pbase = phys; 153269601Snwhitehorn sc->memh = sparc64_fake_bustag(space, phys, &sc->memt[0]); 154269601Snwhitehorn 155269601Snwhitehorn /* 32-bit VGA palette */ 156271112Semaste vt_generate_cons_palette(sc->fb.fb_cmap, COLOR_FORMAT_RGB, 157271112Semaste 255, 0, 255, 8, 255, 16); 158271112Semaste sc->fb.fb_cmsize = 16; 159269601Snwhitehorn 160269601Snwhitehorn vt_fb_init(vd); 161269601Snwhitehorn 162269601Snwhitehorn return (CN_INTERNAL); 163269601Snwhitehorn} 164269601Snwhitehorn 165269601Snwhitehornstatic void 166269601Snwhitehorncreatorfb_blank(struct vt_device *vd, term_color_t color) 167269601Snwhitehorn{ 168269601Snwhitehorn struct creatorfb_softc *sc; 169269601Snwhitehorn uint32_t c; 170269601Snwhitehorn int i; 171269601Snwhitehorn 172269601Snwhitehorn sc = vd->vd_softc; 173269601Snwhitehorn c = sc->fb.fb_cmap[color]; 174269601Snwhitehorn 175269601Snwhitehorn for (i = 0; i < sc->fb.fb_height; i++) 176269601Snwhitehorn bus_space_set_region_4(sc->memt, sc->memh, i*sc->fb.fb_stride, 177269601Snwhitehorn c, sc->fb.fb_width); 178269601Snwhitehorn} 179269601Snwhitehorn 180269601Snwhitehornstatic void 181271128Semastecreatorfb_bitblt_bitmap(struct vt_device *vd, const struct vt_window *vw, 182271128Semaste const uint8_t *pattern, const uint8_t *mask, 183271128Semaste unsigned int width, unsigned int height, 184271128Semaste unsigned int x, unsigned int y, term_color_t fg, term_color_t bg) 185269601Snwhitehorn{ 186269601Snwhitehorn struct creatorfb_softc *sc = vd->vd_softc; 187269601Snwhitehorn u_long line; 188269601Snwhitehorn uint32_t fgc, bgc; 189271128Semaste int c, l; 190269601Snwhitehorn uint8_t b, m; 191269601Snwhitehorn 192269601Snwhitehorn fgc = sc->fb.fb_cmap[fg]; 193269601Snwhitehorn bgc = sc->fb.fb_cmap[bg]; 194269601Snwhitehorn b = m = 0; 195269601Snwhitehorn 196271128Semaste line = (sc->fb.fb_stride * y) + 4*x; 197271128Semaste for (l = 0; 198271128Semaste l < height && y + l < vw->vw_draw_area.tr_end.tp_row; 199271128Semaste l++) { 200271128Semaste for (c = 0; 201271128Semaste c < width && x + c < vw->vw_draw_area.tr_end.tp_col; 202271128Semaste c++) { 203269601Snwhitehorn if (c % 8 == 0) 204271128Semaste b = *pattern++; 205269601Snwhitehorn else 206269601Snwhitehorn b <<= 1; 207269601Snwhitehorn if (mask != NULL) { 208269601Snwhitehorn if (c % 8 == 0) 209269601Snwhitehorn m = *mask++; 210269601Snwhitehorn else 211269601Snwhitehorn m <<= 1; 212269601Snwhitehorn /* Skip pixel write if mask not set. */ 213269601Snwhitehorn if ((m & 0x80) == 0) 214269601Snwhitehorn continue; 215269601Snwhitehorn } 216269601Snwhitehorn bus_space_write_4(sc->memt, sc->memh, line + 4*c, 217269601Snwhitehorn (b & 0x80) ? fgc : bgc); 218269601Snwhitehorn } 219269601Snwhitehorn line += sc->fb.fb_stride; 220269601Snwhitehorn } 221269601Snwhitehorn} 222269601Snwhitehorn 223271128Semastevoid 224271128Semastecreatorfb_bitblt_text(struct vt_device *vd, const struct vt_window *vw, 225271128Semaste const term_rect_t *area) 226271128Semaste{ 227271128Semaste unsigned int col, row, x, y; 228271128Semaste struct vt_font *vf; 229271128Semaste term_char_t c; 230271128Semaste term_color_t fg, bg; 231271128Semaste const uint8_t *pattern; 232271128Semaste 233271128Semaste vf = vw->vw_font; 234271128Semaste 235271128Semaste for (row = area->tr_begin.tp_row; row < area->tr_end.tp_row; ++row) { 236271128Semaste for (col = area->tr_begin.tp_col; col < area->tr_end.tp_col; 237271128Semaste ++col) { 238271128Semaste x = col * vf->vf_width + 239271128Semaste vw->vw_draw_area.tr_begin.tp_col; 240271128Semaste y = row * vf->vf_height + 241271128Semaste vw->vw_draw_area.tr_begin.tp_row; 242271128Semaste 243271128Semaste c = VTBUF_GET_FIELD(&vw->vw_buf, row, col); 244271128Semaste pattern = vtfont_lookup(vf, c); 245271128Semaste vt_determine_colors(c, 246271128Semaste VTBUF_ISCURSOR(&vw->vw_buf, row, col), &fg, &bg); 247271128Semaste 248271128Semaste creatorfb_bitblt_bitmap(vd, vw, 249271128Semaste pattern, NULL, vf->vf_width, vf->vf_height, 250271128Semaste x, y, fg, bg); 251271128Semaste } 252271128Semaste } 253271128Semaste 254271128Semaste#ifndef SC_NO_CUTPASTE 255271128Semaste if (!vd->vd_mshown) 256271128Semaste return; 257271128Semaste 258271128Semaste term_rect_t drawn_area; 259271128Semaste 260271128Semaste drawn_area.tr_begin.tp_col = area->tr_begin.tp_col * vf->vf_width; 261271128Semaste drawn_area.tr_begin.tp_row = area->tr_begin.tp_row * vf->vf_height; 262271128Semaste drawn_area.tr_end.tp_col = area->tr_end.tp_col * vf->vf_width; 263271128Semaste drawn_area.tr_end.tp_row = area->tr_end.tp_row * vf->vf_height; 264271128Semaste 265271128Semaste if (vt_is_cursor_in_area(vd, &drawn_area)) { 266271128Semaste creatorfb_bitblt_bitmap(vd, vw, 267271128Semaste vd->vd_mcursor->map, vd->vd_mcursor->mask, 268271128Semaste vd->vd_mcursor->width, vd->vd_mcursor->height, 269271128Semaste vd->vd_mx_drawn + vw->vw_draw_area.tr_begin.tp_col, 270271128Semaste vd->vd_my_drawn + vw->vw_draw_area.tr_begin.tp_row, 271271128Semaste vd->vd_mcursor_fg, vd->vd_mcursor_bg); 272271128Semaste } 273271128Semaste#endif 274271128Semaste} 275