1/* $NetBSD: rbox.c,v 1.4 2023/01/15 06:19:45 tsutsui Exp $ */ 2/* $OpenBSD: rbox.c,v 1.14 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_rb.c 1.15 93/08/13$ 91 * 92 * @(#)grf_rb.c 8.4 (Berkeley) 1/12/94 93 */ 94 95/* 96 * Graphics routines for the Renaissance, HP98720 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/rboxreg.h> 122 123struct rbox_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 rbox_dio_match(device_t, cfdata_t, void *); 131static void rbox_dio_attach(device_t, device_t, void *); 132static int rbox_intio_match(device_t, cfdata_t, void *); 133static void rbox_intio_attach(device_t, device_t, void *); 134 135CFATTACH_DECL_NEW(rbox_dio, sizeof(struct rbox_softc), 136 rbox_dio_match, rbox_dio_attach, NULL, NULL); 137 138CFATTACH_DECL_NEW(rbox_intio, sizeof(struct rbox_softc), 139 rbox_intio_match, rbox_intio_attach, NULL, NULL); 140 141static int rbox_reset(struct diofb *, int, struct diofbreg *); 142static void rbox_restore(struct diofb *); 143static int rbox_windowmove(struct diofb *, uint16_t, uint16_t, uint16_t, 144 uint16_t, uint16_t, uint16_t, int16_t, int16_t); 145 146static int rbox_ioctl(void *, void *, u_long, void *, int, struct lwp *); 147 148static struct wsdisplay_accessops rbox_accessops = { 149 rbox_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 162rbox_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_RENAISSANCE) { 176 return 1; 177 } 178 179 return 0; 180} 181 182void 183rbox_intio_attach(device_t parent, device_t self, void *aux) 184{ 185 struct rbox_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 rbox_reset(sc->sc_fb, sc->sc_scode, fbr); 198 } 199 200 diofb_end_attach(self, &rbox_accessops, sc->sc_fb, 201 sc->sc_scode == conscode, NULL); 202} 203 204int 205rbox_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_RENAISSANCE) 211 return 1; 212 213 return 0; 214} 215 216void 217rbox_dio_attach(device_t parent, device_t self, void *aux) 218{ 219 struct rbox_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, 232 0, &bsh)) { 233 aprint_error(": can't map framebuffer\n"); 234 return; 235 } 236 fbr = bus_space_vaddr(da->da_bst, bsh); 237 if (rbox_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, &rbox_accessops, sc->sc_fb, 244 sc->sc_scode == conscode, NULL); 245} 246 247/* 248 * Initialize hardware and display routines. 249 */ 250int 251rbox_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 = rbox_windowmove; 266 rbox_restore(fb); 267 diofb_fbsetup(fb); 268 269 return 0; 270} 271 272void 273rbox_restore(struct diofb *fb) 274{ 275 volatile struct rboxfb *rb = (struct rboxfb *)fb->regkva; 276 u_int i; 277 278 rb_waitbusy(rb); 279 280 rb->regs.id = GRFHWID; /* trigger reset */ 281 DELAY(1000); 282 283 rb->regs.interrupt = 0x04; 284 rb->video_enable = 0x01; 285 rb->drive = 0x01; 286 rb->vdrive = 0x0; 287 288 rb->opwen = 0xFF; 289 290 /* 291 * Clear color map 292 */ 293 rb_waitbusy(fb->regkva); 294 for (i = 0; i < 16; i++) { 295 *(fb->regkva + 0x63c3 + i*4) = 0x0; 296 *(fb->regkva + 0x6403 + i*4) = 0x0; 297 *(fb->regkva + 0x6803 + i*4) = 0x0; 298 *(fb->regkva + 0x6c03 + i*4) = 0x0; 299 *(fb->regkva + 0x73c3 + i*4) = 0x0; 300 *(fb->regkva + 0x7403 + i*4) = 0x0; 301 *(fb->regkva + 0x7803 + i*4) = 0x0; 302 *(fb->regkva + 0x7c03 + i*4) = 0x0; 303 } 304 305 rb->rep_rule = RBOX_DUALROP(RR_COPY); 306 307 /* 308 * I cannot figure out how to make the blink planes stop. So, we 309 * must set both colormaps so that when the planes blink, and 310 * the secondary colormap is active, we still get text. 311 */ 312 CM1RED(fb)[0x00].value = 0x00; 313 CM1GRN(fb)[0x00].value = 0x00; 314 CM1BLU(fb)[0x00].value = 0x00; 315 CM1RED(fb)[0x01].value = 0xFF; 316 CM1GRN(fb)[0x01].value = 0xFF; 317 CM1BLU(fb)[0x01].value = 0xFF; 318 319 CM2RED(fb)[0x00].value = 0x00; 320 CM2GRN(fb)[0x00].value = 0x00; 321 CM2BLU(fb)[0x00].value = 0x00; 322 CM2RED(fb)[0x01].value = 0xFF; 323 CM2GRN(fb)[0x01].value = 0xFF; 324 CM2BLU(fb)[0x01].value = 0xFF; 325 326 rb->blink = 0x00; 327 rb->write_enable = 0x01; 328 rb->opwen = 0x00; 329 330 /* enable display */ 331 rb->display_enable = 0x01; 332} 333 334int 335rbox_ioctl(void *v, void *vs, u_long cmd, void *data, int flags, struct lwp *l) 336{ 337 struct diofb *fb = v; 338 struct wsdisplay_fbinfo *wdf; 339 340 switch (cmd) { 341 case WSDISPLAYIO_GTYPE: 342 *(u_int *)data = WSDISPLAY_TYPE_RBOX; 343 return 0; 344 case WSDISPLAYIO_SMODE: 345 fb->mapmode = *(u_int *)data; 346 if (fb->mapmode == WSDISPLAYIO_MODE_EMUL) 347 rbox_restore(fb); 348 return 0; 349 case WSDISPLAYIO_GINFO: 350 wdf = (void *)data; 351 wdf->width = fb->ri.ri_width; 352 wdf->height = fb->ri.ri_height; 353 wdf->depth = fb->ri.ri_depth; 354 wdf->cmsize = 0; /* XXX */ 355 return 0; 356 case WSDISPLAYIO_LINEBYTES: 357 *(u_int *)data = fb->ri.ri_stride; 358 return 0; 359 case WSDISPLAYIO_GETCMAP: 360 case WSDISPLAYIO_PUTCMAP: 361 /* XXX until color support is implemented */ 362 return EPASSTHROUGH; 363 case WSDISPLAYIO_GVIDEO: 364 case WSDISPLAYIO_SVIDEO: 365 return EPASSTHROUGH; 366 } 367 368 return EPASSTHROUGH; 369} 370 371int 372rbox_windowmove(struct diofb *fb, uint16_t sx, uint16_t sy, 373 uint16_t dx, uint16_t dy, uint16_t cx, uint16_t cy, int16_t rop, 374 int16_t planemask) 375{ 376 volatile struct rboxfb *rb = (struct rboxfb *)fb->regkva; 377 378 if (planemask != 0xff) 379 return EINVAL; 380 381 rb_waitbusy(rb); 382 383 rb->rep_rule = RBOX_DUALROP(rop); 384 rb->source_y = sy; 385 rb->source_x = sx; 386 rb->dest_y = dy; 387 rb->dest_x = dx; 388 rb->wheight = cy; 389 rb->wwidth = cx; 390 rb->wmove = 1; 391 392 rb_waitbusy(rb); 393 394 return 0; 395} 396 397/* 398 * Renaissance console support 399 */ 400int 401rboxcnattach(bus_space_tag_t bst, bus_addr_t addr, int scode) 402{ 403 bus_space_handle_t bsh; 404 void *va; 405 struct diofbreg *fbr; 406 struct diofb *fb = &diofb_cn; 407 int size; 408 409 if (bus_space_map(bst, addr, PAGE_SIZE, 0, &bsh)) 410 return 1; 411 va = bus_space_vaddr(bst, bsh); 412 fbr = va; 413 414 if (badaddr(va) || 415 (fbr->id != GRFHWID) || (fbr->fbid != GID_RENAISSANCE)) { 416 bus_space_unmap(bst, bsh, PAGE_SIZE); 417 return 1; 418 } 419 420 size = DIO_SIZE(scode, va); 421 422 bus_space_unmap(bst, bsh, PAGE_SIZE); 423 if (bus_space_map(bst, addr, size, 0, &bsh)) 424 return 1; 425 va = bus_space_vaddr(bst, bsh); 426 427 /* 428 * Initialize the framebuffer hardware. 429 */ 430 conscode = scode; 431 conaddr = va; 432 rbox_reset(fb, conscode, (struct diofbreg *)conaddr); 433 434 /* 435 * Initialize the terminal emulator. 436 */ 437 diofb_cnattach(fb); 438 return 0; 439} 440