1/* $NetBSD: tvrx.c,v 1.2 2011/02/12 16:40:29 tsutsui Exp $ */ 2/* $OpenBSD: tvrx.c,v 1.1 2006/04/14 21:05:43 miod Exp $ */ 3 4/* 5 * Copyright (c) 2006, Miodrag Vallat. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 26 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 * 29 */ 30 31/* 32 * Graphics routines for the TurboVRX frame buffer 33 */ 34 35#include <sys/param.h> 36#include <sys/systm.h> 37#include <sys/conf.h> 38#include <sys/device.h> 39#include <sys/proc.h> 40#include <sys/ioctl.h> 41#include <sys/bus.h> 42#include <sys/cpu.h> 43 44#include <machine/autoconf.h> 45 46#include <hp300/dev/dioreg.h> 47#include <hp300/dev/diovar.h> 48#include <hp300/dev/diodevs.h> 49 50#include <dev/cons.h> 51 52#include <dev/wscons/wsconsio.h> 53#include <dev/wscons/wsdisplayvar.h> 54#include <dev/rasops/rasops.h> 55 56#include <hp300/dev/diofbreg.h> 57#include <hp300/dev/diofbvar.h> 58 59struct tvrx_softc { 60 device_t sc_dev; 61 struct diofb *sc_fb; 62 struct diofb sc_fb_store; 63 int sc_scode; 64}; 65 66static int tvrx_match(device_t, cfdata_t, void *); 67static void tvrx_attach(device_t, device_t, void *); 68 69CFATTACH_DECL_NEW(tvrx, sizeof(struct tvrx_softc), 70 tvrx_match, tvrx_attach, NULL, NULL); 71 72static int tvrx_reset(struct diofb *, int, struct diofbreg *); 73 74static int tvrx_ioctl(void *, void *, u_long, void *, int, struct lwp *); 75 76static struct wsdisplay_accessops tvrx_accessops = { 77 tvrx_ioctl, 78 diofb_mmap, 79 diofb_alloc_screen, 80 diofb_free_screen, 81 diofb_show_screen, 82 NULL, /* load_font */ 83}; 84 85/* 86 * Attachment glue 87 */ 88 89int 90tvrx_match(device_t parent, cfdata_t cf, void *aux) 91{ 92 struct dio_attach_args *da = aux; 93 94 if (da->da_id != DIO_DEVICE_ID_FRAMEBUFFER || 95 da->da_secid != DIO_DEVICE_SECID_TIGERSHARK) 96 return 0; 97 98 return 1; 99} 100 101void 102tvrx_attach(device_t parent, device_t self, void *aux) 103{ 104 struct tvrx_softc *sc = device_private(self); 105 struct dio_attach_args *da = aux; 106 bus_space_handle_t bsh; 107 struct diofbreg *fbr; 108 109 sc->sc_dev = self; 110 sc->sc_scode = da->da_scode; 111 if (sc->sc_scode == conscode) { 112 fbr = (struct diofbreg *)conaddr; /* already mapped */ 113 sc->sc_fb = &diofb_cn; 114 } else { 115 sc->sc_fb = &sc->sc_fb_store; 116 if (bus_space_map(da->da_bst, da->da_addr, da->da_size, 0, 117 &bsh)) { 118 aprint_error(": can't map framebuffer\n"); 119 return; 120 } 121 fbr = bus_space_vaddr(da->da_bst, bsh); 122 if (tvrx_reset(sc->sc_fb, sc->sc_scode, fbr) != 0) { 123 aprint_error(": can't reset framebuffer\n"); 124 return; 125 } 126 } 127 128 diofb_end_attach(self, &tvrx_accessops, sc->sc_fb, 129 sc->sc_scode == conscode, NULL); 130} 131 132/* 133 * Initialize hardware and display routines. 134 */ 135int 136tvrx_reset(struct diofb *fb, int scode, struct diofbreg *fbr) 137{ 138 int rc; 139 140 if ((rc = diofb_fbinquire(fb, scode, fbr)) != 0) 141 return rc; 142 143 /* 144 * We rely on the PROM to initialize the frame buffer in the mode 145 * we expect it: cleared, overlay plane enabled and accessible 146 * at the beginning of the video memory. 147 * 148 * This is NOT the mode we would end up by simply resetting the 149 * board. 150 */ 151 152 fb->ri.ri_depth = 1; 153 fb->bmv = diofb_mono_windowmove; 154 diofb_fbsetup(fb); 155 156 return 0; 157} 158 159int 160tvrx_ioctl(void *v, void *vs, u_long cmd, void *data, int flags, struct lwp *l) 161{ 162 struct diofb *fb = v; 163 struct wsdisplay_fbinfo *wdf; 164 165 switch (cmd) { 166 case WSDISPLAYIO_GTYPE: 167 *(u_int *)data = WSDISPLAY_TYPE_TVRX; 168 return 0; 169 case WSDISPLAYIO_SMODE: 170 fb->mapmode = *(u_int *)data; 171 return 0; 172 case WSDISPLAYIO_GINFO: 173 wdf = (void *)data; 174 wdf->width = fb->ri.ri_width; 175 wdf->height = fb->ri.ri_height; 176 wdf->depth = fb->ri.ri_depth; 177 wdf->cmsize = 0; 178 return 0; 179 case WSDISPLAYIO_LINEBYTES: 180 *(u_int *)data = fb->ri.ri_stride; 181 return 0; 182 case WSDISPLAYIO_GETCMAP: 183 case WSDISPLAYIO_PUTCMAP: 184 /* until color support is implemented */ 185 return EPASSTHROUGH; 186 case WSDISPLAYIO_GVIDEO: 187 case WSDISPLAYIO_SVIDEO: 188 /* unsupported */ 189 return EPASSTHROUGH; 190 } 191 192 return EPASSTHROUGH; 193} 194 195/* 196 * Console support 197 */ 198 199int 200tvrxcnattach(bus_space_tag_t bst, bus_addr_t addr, int scode) 201{ 202 bus_space_handle_t bsh; 203 void *va; 204 struct diofbreg *fbr; 205 struct diofb *fb = &diofb_cn; 206 int size; 207 208 if (bus_space_map(bst, addr, PAGE_SIZE, 0, &bsh)) 209 return 1; 210 va = bus_space_vaddr(bst, bsh); 211 fbr = va; 212 213 if (badaddr(va) || 214 fbr->id != GRFHWID || fbr->fbid == GID_TIGER) { 215 bus_space_unmap(bst, bsh, PAGE_SIZE); 216 return 1; 217 } 218 219 size = DIO_SIZE(scode, va); 220 221 bus_space_unmap(bst, bsh, PAGE_SIZE); 222 if (bus_space_map(bst, addr, size, 0, &bsh)) 223 return 1; 224 va = bus_space_vaddr(bst, bsh); 225 226 /* 227 * Initialize the framebuffer hardware. 228 */ 229 conscode = scode; 230 conaddr = va; 231 tvrx_reset(fb, conscode, (struct diofbreg *)conaddr); 232 233 /* 234 * Initialize the terminal emulator. 235 */ 236 diofb_cnattach(fb); 237 return 0; 238} 239