1/* $NetBSD: tft.c,v 1.7 2021/08/07 16:18:52 thorpej Exp $ */ 2 3/* 4 * Copyright (c) 2006 Jachym Holecek 5 * All rights reserved. 6 * 7 * Written for DFC Design, s.r.o. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include <sys/cdefs.h> 33__KERNEL_RCSID(0, "$NetBSD: tft.c,v 1.7 2021/08/07 16:18:52 thorpej Exp $"); 34 35#include <sys/param.h> 36#include <sys/systm.h> 37#include <sys/mbuf.h> 38#include <sys/kernel.h> 39#include <sys/socket.h> 40#include <sys/ioctl.h> 41#include <sys/device.h> 42#include <sys/queue.h> 43 44#include <uvm/uvm_extern.h> 45 46#include <sys/bus.h> 47 48#include <dev/wscons/wsdisplayvar.h> 49#include <dev/wscons/wsconsio.h> 50#include <dev/wsfont/wsfont.h> 51#include <dev/rasops/rasops.h> 52#include <dev/splash/splash.h> 53#include <dev/wscons/wsdisplay_vconsvar.h> 54 55#include <evbppc/virtex/dev/tftreg.h> 56#include <evbppc/virtex/dev/tftvar.h> 57 58 59/* Template. */ 60static struct wsscreen_descr tft_screen = { 61 .name = "fb", 62 .fontwidth = 8, 63 .fontheight = 16, 64 .capabilities = (WSSCREEN_WSCOLORS | WSSCREEN_HILIT | 65 WSSCREEN_UNDERLINE | WSSCREEN_REVERSE), 66}; 67 68static void tft_init_screen(void *, struct vcons_screen *, int, long *); 69 70 71void 72tft_attach(device_t self, struct wsdisplay_accessops *accessops) 73{ 74 struct wsemuldisplaydev_attach_args waa; 75 struct tft_softc *sc = device_private(self); 76 struct rasops_info *ri; 77 long defattr; 78 79 KASSERT(accessops->mmap); 80 81 if (accessops->ioctl == NULL) 82 accessops->ioctl = tft_ioctl; 83 84 printf("%s: %ux%ux%ub\n", device_xname(self), sc->sc_width, 85 sc->sc_height, sc->sc_bpp); 86 printf("%s: video memory va %p size %uB stride %uB\n", 87 device_xname(self), sc->sc_image, sc->sc_size, sc->sc_stride); 88 89 memset(sc->sc_image, 0xf0, sc->sc_size); 90 91 /* Setup descr template, make up list. */ 92 sc->sc_ws_descr_storage[0] = tft_screen; /* struct copy */ 93 sc->sc_ws_descr = sc->sc_ws_descr_storage; 94 sc->sc_ws_scrlist.nscreens = 1; 95 sc->sc_ws_scrlist.screens = (void *) &sc->sc_ws_descr; 96 97 vcons_init(&sc->sc_vc_data, self, sc->sc_ws_descr, accessops); 98 99 sc->sc_vc_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; 100 sc->sc_vc_data.init_screen = tft_init_screen; 101 sc->sc_vc_data.cookie = sc; 102 103 vcons_init_screen(&sc->sc_vc_data, &sc->sc_vc_screen, 1, &defattr); 104 105 /* Patch descr. */ 106 ri = &sc->sc_vc_screen.scr_ri; 107 sc->sc_ws_descr->textops = &ri->ri_ops; 108 sc->sc_ws_descr->capabilities = ri->ri_caps; 109 sc->sc_ws_descr->nrows = ri->ri_rows; 110 sc->sc_ws_descr->ncols = ri->ri_cols; 111 112#ifdef SPLASHSCREEN 113 sc->sc_sp_info.si_depth = ri->ri_depth; 114 sc->sc_sp_info.si_bits = ri->ri_bits; 115 sc->sc_sp_info.si_hwbits = ri->ri_hwbits; 116 sc->sc_sp_info.si_width = ri->ri_width; 117 sc->sc_sp_info.si_height = ri->ri_height; 118 sc->sc_sp_info.si_stride = ri->ri_stride; 119 sc->sc_sp_info.si_fillrect = NULL; 120 121 if (splash_render(&sc->sc_sp_info, SPLASH_F_CENTER|SPLASH_F_FILL) == 0) 122 SCREEN_DISABLE_DRAWING(&sc->sc_vc_screen); 123#endif 124 125 if (sc->sc_sdhook == NULL) { 126 sc->sc_sdhook = shutdownhook_establish(tft_shutdown, self); 127 if (sc->sc_sdhook == NULL) 128 printf("%s: WARNING: unable to establish shutdown " 129 "hook\n", device_xname(self)); 130 } 131 132 waa.console = 0; /* XXX */ 133 waa.scrdata = &sc->sc_ws_scrlist; 134 waa.accessops = accessops; 135 waa.accesscookie = &sc->sc_vc_data; 136 137 config_found(self, &waa, wsemuldisplaydevprint, CFARGS_NONE); 138} 139 140static void 141tft_init_screen(void *cookie, struct vcons_screen *scr, int existing, 142 long *defattr) 143{ 144 struct tft_softc *sc = cookie; 145 struct rasops_info *ri = &scr->scr_ri; 146 147 /* initialize font subsystem */ 148 wsfont_init(); 149 150 ri->ri_depth = sc->sc_bpp; 151 ri->ri_width = sc->sc_width; 152 ri->ri_height = sc->sc_height; 153 ri->ri_stride = sc->sc_stride; 154 ri->ri_flg = /*RI_CENTER |*/ RI_CLEAR; 155 ri->ri_bits = (void *)sc->sc_image; 156 ri->ri_caps = WSSCREEN_WSCOLORS; 157 158 ri->ri_rnum = 8; 159 ri->ri_gnum = 8; 160 ri->ri_bnum = 8; 161 ri->ri_rpos = 16; 162 ri->ri_gpos = 8; 163 ri->ri_bpos = 0; 164 165 rasops_init(ri, ri->ri_height / 16, ri->ri_width / 8); 166 167 /* we'd override rasops methods now if we had acceleration */ 168} 169 170void 171tft_shutdown(void *arg) 172{ 173 struct tft_softc *sc = arg; 174 175 bus_space_write_4(sc->sc_iot, sc->sc_ioh, TFT_CTRL, CTRL_RESET); 176} 177 178int 179tft_mode(device_t dev) 180{ 181 struct tft_softc *sc = device_private(dev); 182 prop_number_t pn; 183 184 /* Defaults for tft core generics. */ 185 sc->sc_width = 640; 186 sc->sc_height = 480; 187 sc->sc_stride = 1024 * 4; 188 sc->sc_bpp = 32; /* 24bit colour, not packed */ 189 190 /* We can make all these mandatory if it becomes practical... */ 191 pn = prop_dictionary_get(device_properties(dev), "x-resolution"); 192 if (pn != NULL) 193 sc->sc_width = (u_int)prop_number_integer_value(pn); 194 195 pn = prop_dictionary_get(device_properties(dev), "y-resolution"); 196 if (pn != NULL) 197 sc->sc_height = (u_int)prop_number_integer_value(pn); 198 199 pn = prop_dictionary_get(device_properties(dev), "stride-bytes"); 200 if (pn != NULL) 201 sc->sc_stride = (u_int)prop_number_integer_value(pn); 202 203 pn = prop_dictionary_get(device_properties(dev), "bits-per-pixel"); 204 if (pn != NULL) 205 sc->sc_bpp = (u_int)prop_number_integer_value(pn); 206 207 sc->sc_size = sc->sc_stride * sc->sc_height; 208 return (0); 209} 210 211int 212tft_ioctl(void *arg, void *scr, u_long cmd, void *data, int flag, 213 struct lwp *l) 214{ 215 struct vcons_data *vd = arg; 216 struct tft_softc *sc = vd->cookie; 217 struct wsdisplay_fbinfo *info; 218 219 switch (cmd) { 220 case WSDISPLAYIO_GTYPE: 221 *(u_int *)data = WSDISPLAY_TYPE_XILFB; 222 return (0); 223 224 case WSDISPLAYIO_GINFO: 225 info = (struct wsdisplay_fbinfo *)data; 226 227 info->height = sc->sc_height; 228 info->width = sc->sc_width; 229 info->depth = sc->sc_bpp; 230 info->cmsize = 0; 231 232 return (0); 233 case WSDISPLAYIO_LINEBYTES: 234 *(u_int *)data = sc->sc_stride; 235 236 return (0); 237 } 238 239 return (EPASSTHROUGH); 240} 241