dvbox.c revision 1.3
1/* $NetBSD: dvbox.c,v 1.3 2011/02/18 19:15:43 tsutsui Exp $ */ 2/* $OpenBSD: dvbox.c,v 1.13 2006/08/11 18:33:13 miod Exp $ */ 3 4/* 5 * Copyright (c) 2005, Miodrag Vallat 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28/*- 29 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. 30 * All rights reserved. 31 * 32 * This code is derived from software contributed to The NetBSD Foundation 33 * by Jason R. Thorpe. 34 * 35 * Redistribution and use in source and binary forms, with or without 36 * modification, are permitted provided that the following conditions 37 * are met: 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 44 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 45 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 46 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 47 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 48 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 49 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 50 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 51 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 52 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 53 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 54 * POSSIBILITY OF SUCH DAMAGE. 55 */ 56 57/* 58 * Copyright (c) 1988 University of Utah. 59 * Copyright (c) 1990, 1993 60 * The Regents of the University of California. All rights reserved. 61 * 62 * This code is derived from software contributed to Berkeley by 63 * the Systems Programming Group of the University of Utah Computer 64 * Science Department. 65 * 66 * Redistribution and use in source and binary forms, with or without 67 * modification, are permitted provided that the following conditions 68 * are met: 69 * 1. Redistributions of source code must retain the above copyright 70 * notice, this list of conditions and the following disclaimer. 71 * 2. Redistributions in binary form must reproduce the above copyright 72 * notice, this list of conditions and the following disclaimer in the 73 * documentation and/or other materials provided with the distribution. 74 * 3. Neither the name of the University nor the names of its contributors 75 * may be used to endorse or promote products derived from this software 76 * without specific prior written permission. 77 * 78 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 79 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 80 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 81 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 82 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 83 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 84 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 85 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 86 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 87 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 88 * SUCH DAMAGE. 89 * 90 * from: Utah $Hdr: grf_dv.c 1.12 93/08/13$ 91 * 92 * @(#)grf_dv.c 8.4 (Berkeley) 1/12/94 93 */ 94 95/* 96 * Graphics routines for the DaVinci, HP98730/98731 Graphics system. 97 */ 98 99#include <sys/param.h> 100#include <sys/systm.h> 101#include <sys/conf.h> 102#include <sys/device.h> 103#include <sys/proc.h> 104#include <sys/ioctl.h> 105#include <sys/bus.h> 106#include <sys/cpu.h> 107 108#include <machine/autoconf.h> 109 110#include <hp300/dev/dioreg.h> 111#include <hp300/dev/diovar.h> 112#include <hp300/dev/diodevs.h> 113#include <hp300/dev/intiovar.h> 114 115#include <dev/wscons/wsconsio.h> 116#include <dev/wscons/wsdisplayvar.h> 117#include <dev/rasops/rasops.h> 118 119#include <hp300/dev/diofbreg.h> 120#include <hp300/dev/diofbvar.h> 121#include <hp300/dev/dvboxreg.h> 122 123struct dvbox_softc { 124 device_t sc_dev; 125 struct diofb *sc_fb; 126 struct diofb sc_fb_store; 127 int sc_scode; 128}; 129 130static int dvbox_dio_match(device_t, cfdata_t, void *); 131static void dvbox_dio_attach(device_t, device_t, void *); 132static int dvbox_intio_match(device_t, cfdata_t, void *); 133static void dvbox_intio_attach(device_t, device_t, void *); 134 135CFATTACH_DECL_NEW(dvbox_dio, sizeof(struct dvbox_softc), 136 dvbox_dio_match, dvbox_dio_attach, NULL, NULL); 137 138CFATTACH_DECL_NEW(dvbox_intio, sizeof(struct dvbox_softc), 139 dvbox_intio_match, dvbox_intio_attach, NULL, NULL); 140 141static int dvbox_reset(struct diofb *, int, struct diofbreg *); 142static void dvbox_restore(struct diofb *); 143static int dvbox_windowmove(struct diofb *, uint16_t, uint16_t, uint16_t, 144 uint16_t, uint16_t, uint16_t, int16_t, int16_t); 145 146static int dvbox_ioctl(void *, void *, u_long, void *, int, struct lwp *); 147 148static struct wsdisplay_accessops dvbox_accessops = { 149 dvbox_ioctl, 150 diofb_mmap, 151 diofb_alloc_screen, 152 diofb_free_screen, 153 diofb_show_screen, 154 NULL, /* load_font */ 155}; 156 157/* 158 * Attachment glue 159 */ 160 161int 162dvbox_intio_match(device_t parent, cfdata_t cf, void *aux) 163{ 164 struct intio_attach_args *ia = aux; 165 struct diofbreg *fbr; 166 167 if (strcmp("fb", ia->ia_modname) != 0) 168 return 0; 169 170 fbr = (struct diofbreg *)ia->ia_addr; 171 172 if (badaddr((void *)fbr)) 173 return 0; 174 175 if (fbr->id == GRFHWID && fbr->fbid == GID_DAVINCI) { 176 return 1; 177 } 178 179 return 0; 180} 181 182void 183dvbox_intio_attach(device_t parent, device_t self, void *aux) 184{ 185 struct dvbox_softc *sc = device_private(self); 186 struct intio_attach_args *ia = aux; 187 struct diofbreg *fbr; 188 189 sc->sc_dev = self; 190 fbr = (struct diofbreg *)ia->ia_addr; 191 sc->sc_scode = CONSCODE_INTERNAL; 192 193 if (sc->sc_scode == conscode) { 194 sc->sc_fb = &diofb_cn; 195 } else { 196 sc->sc_fb = &sc->sc_fb_store; 197 dvbox_reset(sc->sc_fb, sc->sc_scode, fbr); 198 } 199 200 diofb_end_attach(self, &dvbox_accessops, sc->sc_fb, 201 sc->sc_scode == conscode, NULL); 202} 203 204int 205dvbox_dio_match(device_t parent, cfdata_t cf, void *aux) 206{ 207 struct dio_attach_args *da = aux; 208 209 if (da->da_id == DIO_DEVICE_ID_FRAMEBUFFER && 210 da->da_secid == DIO_DEVICE_SECID_DAVINCI) 211 return 1; 212 213 return 0; 214} 215 216void 217dvbox_dio_attach(device_t parent, device_t self, void *aux) 218{ 219 struct dvbox_softc *sc = device_private(self); 220 struct dio_attach_args *da = aux; 221 bus_space_handle_t bsh; 222 struct diofbreg *fbr; 223 224 sc->sc_dev = self; 225 sc->sc_scode = da->da_scode; 226 if (sc->sc_scode == conscode) { 227 fbr = (struct diofbreg *)conaddr; /* already mapped */ 228 sc->sc_fb = &diofb_cn; 229 } else { 230 sc->sc_fb = &sc->sc_fb_store; 231 if (bus_space_map(da->da_bst, da->da_addr, da->da_size, 0, 232 &bsh)) { 233 aprint_error(": can't map framebuffer\n"); 234 return; 235 } 236 fbr = bus_space_vaddr(da->da_bst, bsh); 237 if (dvbox_reset(sc->sc_fb, sc->sc_scode, fbr) != 0) { 238 aprint_error(": can't reset framebuffer\n"); 239 return; 240 } 241 } 242 243 diofb_end_attach(self, &dvbox_accessops, sc->sc_fb, 244 sc->sc_scode == conscode, NULL); 245} 246 247/* 248 * Initialize hardware and display routines. 249 */ 250int 251dvbox_reset(struct diofb *fb, int scode, struct diofbreg *fbr) 252{ 253 int rc; 254 255 if ((rc = diofb_fbinquire(fb, scode, fbr)) != 0) 256 return rc; 257 258 /* 259 * Restrict the framebuffer to a monochrome view for now, until 260 * I know better how to detect and frob overlay planes, and 261 * setup a proper colormap. -- miod 262 */ 263 fb->planes = fb->planemask = 1; 264 265 fb->bmv = dvbox_windowmove; 266 dvbox_restore(fb); 267 diofb_fbsetup(fb); 268 269 return 0; 270} 271 272/* 273 * Magic initialization code. 274 */ 275void 276dvbox_restore(struct diofb *fb) 277{ 278 volatile struct dvboxfb *db = (struct dvboxfb *)fb->regkva; 279 u_int i; 280 281 db->regs.id = 0x80; 282 DELAY(100); 283 284 db->regs.interrupt = 0x04; 285 db->en_scan = 0x01; 286 db->fbwen = ~0; 287 db->opwen = ~0; 288 db->fold = 0x01; /* 8bpp */ 289 db->drive = 0x01; /* use FB plane */ 290 db->rep_rule = DVBOX_DUALROP(RR_COPY); 291 db->alt_rr = DVBOX_DUALROP(RR_COPY); 292 db->zrr = DVBOX_DUALROP(RR_COPY); 293 294 db->fbvenp = 0xFF; /* enable video */ 295 db->dispen = 0x01; /* enable display */ 296 db->fbvens = 0x0; 297 db->fv_trig = 0x01; 298 DELAY(100); 299 db->vdrive = 0x0; 300 db->zconfig = 0x0; 301 302 while (db->wbusy & 0x01) 303 DELAY(10); 304 305 db->cmapbank = 0; 306 307 db->red0 = 0; 308 db->red1 = 0; 309 db->green0 = 0; 310 db->green1 = 0; 311 db->blue0 = 0; 312 db->blue1 = 0; 313 314 db->panxh = 0; 315 db->panxl = 0; 316 db->panyh = 0; 317 db->panyl = 0; 318 db->zoom = 0; 319 db->cdwidth = 0x50; 320 db->chstart = 0x52; 321 db->cvwidth = 0x22; 322 db->pz_trig = 1; 323 324 /* 325 * Turn on frame buffer, turn on overlay planes, set replacement 326 * rule, enable top overlay plane writes for ite, disable all frame 327 * buffer planes, set byte per pixel, and display frame buffer 0. 328 * Lastly, turn on the box. 329 */ 330 db->regs.interrupt = 0x04; 331 db->drive = 0x10; 332 db->rep_rule = DVBOX_DUALROP(RR_COPY); 333 db->opwen = 0x01; 334 db->fbwen = 0x0; 335 db->fold = 0x01; 336 db->vdrive = 0x0; 337 db->dispen = 0x01; 338 339 /* 340 * Video enable top overlay plane. 341 */ 342 db->opvenp = 0x01; 343 db->opvens = 0x01; 344 345 /* 346 * Make sure that overlay planes override frame buffer planes. 347 */ 348 db->ovly0p = 0x0; 349 db->ovly0s = 0x0; 350 db->ovly1p = 0x0; 351 db->ovly1s = 0x0; 352 db->fv_trig = 0x1; 353 DELAY(100); 354 355 /* 356 * Setup the overlay colormaps. Need to set the 0,1 (black/white) 357 * color for both banks. 358 */ 359 db_waitbusy(db); 360 for (i = 0; i <= 1; i++) { 361 db->cmapbank = i; 362 db->rgb[0].red = 0x00; 363 db->rgb[0].green = 0x00; 364 db->rgb[0].blue = 0x00; 365 db->rgb[1].red = 0xff; 366 db->rgb[1].green = 0xff; 367 db->rgb[1].blue = 0xff; 368 } 369 db->cmapbank = 0; 370 db_waitbusy(db); 371} 372 373int 374dvbox_ioctl(void *v, void *vs, u_long cmd, void *data, int flags, struct lwp *l) 375{ 376 struct diofb *fb = v; 377 struct wsdisplay_fbinfo *wdf; 378 379 switch (cmd) { 380 case WSDISPLAYIO_GTYPE: 381 *(u_int *)data = WSDISPLAY_TYPE_DVBOX; 382 return 0; 383 case WSDISPLAYIO_SMODE: 384 fb->mapmode = *(u_int *)data; 385 if (fb->mapmode == WSDISPLAYIO_MODE_EMUL) 386 dvbox_restore(fb); 387 return 0; 388 case WSDISPLAYIO_GINFO: 389 wdf = (void *)data; 390 wdf->width = fb->ri.ri_width; 391 wdf->height = fb->ri.ri_height; 392 wdf->depth = fb->ri.ri_depth; 393 wdf->cmsize = 0; /* XXX */ 394 return 0; 395 case WSDISPLAYIO_LINEBYTES: 396 *(u_int *)data = fb->ri.ri_stride; 397 return 0; 398 case WSDISPLAYIO_GETCMAP: 399 case WSDISPLAYIO_PUTCMAP: 400 /* XXX until color support is implemented */ 401 return EPASSTHROUGH; 402 case WSDISPLAYIO_GVIDEO: 403 case WSDISPLAYIO_SVIDEO: 404 return EPASSTHROUGH; 405 } 406 407 return EPASSTHROUGH; 408} 409 410int 411dvbox_windowmove(struct diofb *fb, uint16_t sx, uint16_t sy, 412 uint16_t dx, uint16_t dy, uint16_t cx, uint16_t cy, int16_t rop, 413 int16_t planemask) 414{ 415 volatile struct dvboxfb *db = (struct dvboxfb *)fb->regkva; 416 417 if (planemask != 0xff) 418 return EINVAL; 419 420 db_waitbusy(db); 421 422 db->rep_rule = DVBOX_DUALROP(rop); 423 db->source_y = sy; 424 db->source_x = sx; 425 db->dest_y = dy; 426 db->dest_x = dx; 427 db->wheight = cy; 428 db->wwidth = cx; 429 db->wmove = 1; 430 431 db_waitbusy(db); 432 433 return 0; 434} 435 436/* 437 * DaVinci console support 438 */ 439 440int 441dvboxcnattach(bus_space_tag_t bst, bus_addr_t addr, int scode) 442{ 443 bus_space_handle_t bsh; 444 void *va; 445 struct diofbreg *fbr; 446 struct diofb *fb = &diofb_cn; 447 int size; 448 449 if (bus_space_map(bst, addr, PAGE_SIZE, 0, &bsh)) 450 return 1; 451 va = bus_space_vaddr(bst, bsh); 452 fbr = va; 453 454 if (badaddr(va) || 455 (fbr->id != GRFHWID) || (fbr->fbid != GID_DAVINCI)) { 456 bus_space_unmap(bst, bsh, PAGE_SIZE); 457 return 1; 458 } 459 460 size = DIO_SIZE(scode, va); 461 462 bus_space_unmap(bst, bsh, PAGE_SIZE); 463 if (bus_space_map(bst, addr, size, 0, &bsh)) 464 return 1; 465 va = bus_space_vaddr(bst, bsh); 466 467 /* 468 * Initialize the framebuffer hardware. 469 */ 470 conscode = scode; 471 conaddr = va; 472 dvbox_reset(fb, conscode, (struct diofbreg *)conaddr); 473 474 /* 475 * Initialize the terminal emulator. 476 */ 477 diofb_cnattach(fb); 478 return 0; 479} 480