tft.c revision 1.2
1/* $NetBSD: tft.c,v 1.2 2007/03/04 05:59:46 christos 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.2 2007/03/04 05:59:46 christos 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 <machine/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 = 96 (const struct wsscreen_descr **)&sc->sc_ws_descr; 97 98 vcons_init(&sc->sc_vc_data, self, sc->sc_ws_descr, accessops); 99 100 sc->sc_vc_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; 101 sc->sc_vc_data.init_screen = tft_init_screen; 102 sc->sc_vc_data.cookie = sc; 103 104 vcons_init_screen(&sc->sc_vc_data, &sc->sc_vc_screen, 1, &defattr); 105 106 /* Patch descr. */ 107 ri = &sc->sc_vc_screen.scr_ri; 108 sc->sc_ws_descr->textops = &ri->ri_ops; 109 sc->sc_ws_descr->capabilities = ri->ri_caps; 110 sc->sc_ws_descr->nrows = ri->ri_rows; 111 sc->sc_ws_descr->ncols = ri->ri_cols; 112 113#ifdef SPLASHSCREEN 114 sc->sc_sp_info.si_depth = ri->ri_depth; 115 sc->sc_sp_info.si_bits = ri->ri_bits; 116 sc->sc_sp_info.si_hwbits = ri->ri_hwbits; 117 sc->sc_sp_info.si_width = ri->ri_width; 118 sc->sc_sp_info.si_height = ri->ri_height; 119 sc->sc_sp_info.si_stride = ri->ri_stride; 120 sc->sc_sp_info.si_fillrect = NULL; 121 122 splash_render(&sc->sc_sp_info, SPLASH_F_CENTER | SPLASH_F_FILL); 123#endif 124 125#ifdef SPLASHSCREEN_PROGRESS 126 sc->sc_sp_progress.sp_top = (sc->sc_height / 8) * 7; 127 sc->sc_sp_progress.sp_width = (sc->sc_width / 4) * 3; 128 sc->sc_sp_progress.sp_left = (sc->sc_width - 129 sc->sc_sp_progress.sp_width) / 2; 130 sc->sc_sp_progress.sp_height = 20; 131 sc->sc_sp_progress.sp_state = -1; 132 sc->sc_sp_progress.sp_si = &sc->sc_sp_info; 133 134 splash_progress_init(&sc->sc_sp_progress); 135 SCREEN_DISABLE_DRAWING(&sc->sc_vc_screen); 136#endif 137 138 if (sc->sc_sdhook == NULL) { 139 sc->sc_sdhook = shutdownhook_establish(tft_shutdown, self); 140 if (sc->sc_sdhook == NULL) 141 printf("%s: WARNING: unable to establish shutdown " 142 "hook\n", device_xname(self)); 143 } 144 145 waa.console = 0; /* XXX */ 146 waa.scrdata = &sc->sc_ws_scrlist; 147 waa.accessops = accessops; 148 waa.accesscookie = &sc->sc_vc_data; 149 150 config_found(self, &waa, wsemuldisplaydevprint); 151} 152 153static void 154tft_init_screen(void *cookie, struct vcons_screen *scr, int existing, 155 long *defattr) 156{ 157 struct tft_softc *sc = cookie; 158 struct rasops_info *ri = &scr->scr_ri; 159 160 /* initialize font subsystem */ 161 wsfont_init(); 162 163 ri->ri_depth = sc->sc_bpp; 164 ri->ri_width = sc->sc_width; 165 ri->ri_height = sc->sc_height; 166 ri->ri_stride = sc->sc_stride; 167 ri->ri_flg = /*RI_CENTER |*/ RI_CLEAR; 168 ri->ri_bits = (void *)sc->sc_image; 169 ri->ri_caps = WSSCREEN_WSCOLORS; 170 171 ri->ri_rnum = 8; 172 ri->ri_gnum = 8; 173 ri->ri_bnum = 8; 174 ri->ri_rpos = 16; 175 ri->ri_gpos = 8; 176 ri->ri_bpos = 0; 177 178 rasops_init(ri, ri->ri_height / 16, ri->ri_width / 8); 179 180 /* we'd override rasops methods now if we had acceleration */ 181} 182 183void 184tft_shutdown(void *arg) 185{ 186 struct tft_softc *sc = arg; 187 188 bus_space_write_4(sc->sc_iot, sc->sc_ioh, TFT_CTRL, CTRL_RESET); 189} 190 191int 192tft_mode(device_t dev) 193{ 194 struct tft_softc *sc = device_private(dev); 195 prop_number_t pn; 196 197 /* Defaults for tft core generics. */ 198 sc->sc_width = 640; 199 sc->sc_height = 480; 200 sc->sc_stride = 1024 * 4; 201 sc->sc_bpp = 32; /* 24bit colour, not packed */ 202 203 /* We can make all these mandatory if it becomes practical... */ 204 pn = prop_dictionary_get(device_properties(dev), "x-resolution"); 205 if (pn != NULL) 206 sc->sc_width = (u_int)prop_number_integer_value(pn); 207 208 pn = prop_dictionary_get(device_properties(dev), "y-resolution"); 209 if (pn != NULL) 210 sc->sc_height = (u_int)prop_number_integer_value(pn); 211 212 pn = prop_dictionary_get(device_properties(dev), "stride-bytes"); 213 if (pn != NULL) 214 sc->sc_stride = (u_int)prop_number_integer_value(pn); 215 216 pn = prop_dictionary_get(device_properties(dev), "bits-per-pixel"); 217 if (pn != NULL) 218 sc->sc_bpp = (u_int)prop_number_integer_value(pn); 219 220 sc->sc_size = sc->sc_stride * sc->sc_height; 221 return (0); 222} 223 224int 225tft_ioctl(void *arg, void *scr, u_long cmd, void *data, int flag, 226 struct lwp *l) 227{ 228 struct vcons_data *vd = arg; 229 struct tft_softc *sc = vd->cookie; 230 struct wsdisplay_fbinfo *info; 231 232 switch (cmd) { 233 case WSDISPLAYIO_GTYPE: 234 *(u_int *)data = WSDISPLAY_TYPE_XILFB; 235 return (0); 236 237 case WSDISPLAYIO_GINFO: 238 info = (struct wsdisplay_fbinfo *)data; 239 240 info->height = sc->sc_height; 241 info->width = sc->sc_width; 242 info->depth = sc->sc_bpp; 243 info->cmsize = 0; 244 245 return (0); 246 case WSDISPLAYIO_LINEBYTES: 247 *(u_int *)data = sc->sc_stride; 248 249 return (0); 250 } 251 252 return (EPASSTHROUGH); 253} 254