1 /* $NetBSD: bwtwo.c,v 1.39 2022/09/25 21:30:29 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 1992, 1993 34 * The Regents of the University of California. All rights reserved. 35 * 36 * This software was developed by the Computer Systems Engineering group 37 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 38 * contributed to Berkeley. 39 * 40 * All advertising materials mentioning features or use of this software 41 * must display the following acknowledgement: 42 * This product includes software developed by the University of 43 * California, Lawrence Berkeley Laboratory. 44 * 45 * Redistribution and use in source and binary forms, with or without 46 * modification, are permitted provided that the following conditions 47 * are met: 48 * 1. Redistributions of source code must retain the above copyright 49 * notice, this list of conditions and the following disclaimer. 50 * 2. Redistributions in binary form must reproduce the above copyright 51 * notice, this list of conditions and the following disclaimer in the 52 * documentation and/or other materials provided with the distribution. 53 * 3. Neither the name of the University nor the names of its contributors 54 * may be used to endorse or promote products derived from this software 55 * without specific prior written permission. 56 * 57 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 58 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 59 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 60 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 61 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 62 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 63 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 64 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 65 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 66 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 67 * SUCH DAMAGE. 68 * 69 * @(#)bwtwo.c 8.1 (Berkeley) 6/11/93 70 */ 71 72 /* 73 * black & white display (bwtwo) driver. 74 * 75 * Does not handle interrupts, even though they can occur. 76 * 77 * P4 and overlay plane support by Jason R. Thorpe <thorpej@NetBSD.org>. 78 * Overlay plane handling hints and ideas provided by Brad Spencer. 79 */ 80 81 #include <sys/cdefs.h> 82 __KERNEL_RCSID(0, "$NetBSD: bwtwo.c,v 1.39 2022/09/25 21:30:29 thorpej Exp $"); 83 84 #include <sys/param.h> 85 #include <sys/systm.h> 86 #include <sys/device.h> 87 #include <sys/ioctl.h> 88 #include <sys/mman.h> 89 #include <sys/tty.h> 90 #include <sys/conf.h> 91 92 #include <machine/autoconf.h> 93 #include <machine/eeprom.h> 94 95 #include <dev/sun/fbio.h> 96 #include <dev/sun/fbvar.h> 97 98 #include <dev/sun/btreg.h> 99 #include <dev/sun/bwtworeg.h> 100 #include <dev/sun/bwtwovar.h> 101 #include <dev/sun/pfourreg.h> 102 103 #if NWSDISPLAY > 0 104 #include <dev/wscons/wsconsio.h> 105 #include <dev/wsfont/wsfont.h> 106 #include <dev/rasops/rasops.h> 107 108 #include "opt_wsemul.h" 109 #endif 110 111 #include "ioconf.h" 112 113 dev_type_open(bwtwoopen); 114 dev_type_ioctl(bwtwoioctl); 115 dev_type_mmap(bwtwommap); 116 117 const struct cdevsw bwtwo_cdevsw = { 118 .d_open = bwtwoopen, 119 .d_close = nullclose, 120 .d_read = noread, 121 .d_write = nowrite, 122 .d_ioctl = bwtwoioctl, 123 .d_stop = nostop, 124 .d_tty = notty, 125 .d_poll = nopoll, 126 .d_mmap = bwtwommap, 127 .d_kqfilter = nokqfilter, 128 .d_discard = nodiscard, 129 .d_flag = D_OTHER 130 }; 131 132 /* XXX we do not handle frame buffer interrupts (do not know how) */ 133 static void bwtwounblank(device_t); 134 135 /* frame buffer generic driver */ 136 static struct fbdriver bwtwofbdriver = { 137 bwtwounblank, bwtwoopen, nullclose, bwtwoioctl, nopoll, bwtwommap, 138 nokqfilter 139 }; 140 141 #if NWSDISPLAY > 0 142 #ifdef RASTERCONSOLE 143 #error RASTERCONSOLE and wsdisplay are mutually exclusive 144 #endif 145 146 struct wsscreen_descr bwtwo_defaultscreen = { 147 "std", 148 0, 0, /* will be filled in -- XXX shouldn't, it's global */ 149 NULL, /* textops */ 150 8, 16, /* font width/height */ 151 0, /* capabilities */ 152 NULL /* modecookie */ 153 }; 154 155 static int bwtwo_ioctl(void *, void *, u_long, void *, int, struct lwp *); 156 static paddr_t bwtwo_mmap(void *, void *, off_t, int); 157 static void bwtwo_init_screen(void *, struct vcons_screen *, int, long *); 158 159 struct wsdisplay_accessops bwtwo_accessops = { 160 bwtwo_ioctl, 161 bwtwo_mmap, 162 NULL, /* alloc_screen */ 163 NULL, /* free_screen */ 164 NULL, /* show_screen */ 165 NULL, /* load_font */ 166 NULL, /* pollc */ 167 NULL /* scroll */ 168 }; 169 170 const struct wsscreen_descr *_bwtwo_scrlist[] = { 171 &bwtwo_defaultscreen 172 }; 173 174 struct wsscreen_list bwtwo_screenlist = { 175 sizeof(_bwtwo_scrlist) / sizeof(struct wsscreen_descr *), 176 _bwtwo_scrlist 177 }; 178 179 180 static struct vcons_screen bw2_console_screen; 181 #endif /* NWSDISPLAY > 0 */ 182 183 int 184 bwtwo_pfour_probe(void *vaddr, void *arg) 185 { 186 cfdata_t cf = arg; 187 188 switch (fb_pfour_id(vaddr)) { 189 case PFOUR_ID_BW: 190 case PFOUR_ID_COLOR8P1: /* bwtwo in ... */ 191 case PFOUR_ID_COLOR24: /* ...overlay plane */ 192 /* This is wrong; should be done in bwtwo_attach() */ 193 cf->cf_flags |= FB_PFOUR; 194 /* FALLTHROUGH */ 195 case PFOUR_NOTPFOUR: 196 return (1); 197 } 198 return (0); 199 } 200 201 void 202 bwtwoattach(struct bwtwo_softc *sc, const char *name, int isconsole) 203 { 204 struct fbdevice *fb = &sc->sc_fb; 205 int isoverlay; 206 #if NWSDISPLAY > 0 207 struct wsemuldisplaydev_attach_args aa; 208 struct rasops_info *ri = &bw2_console_screen.scr_ri; 209 unsigned long defattr = 0; 210 #endif 211 212 /* Fill in the remaining fbdevice values */ 213 fb->fb_driver = &bwtwofbdriver; 214 fb->fb_device = sc->sc_dev; 215 fb->fb_type.fb_type = FBTYPE_SUN2BW; 216 fb->fb_type.fb_cmsize = 0; 217 fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes; 218 printf(": %s, %d x %d", name, 219 fb->fb_type.fb_width, fb->fb_type.fb_height); 220 221 /* Are we an overlay bw2? */ 222 if ((fb->fb_flags & FB_PFOUR) == 0 || (sc->sc_ovtype == BWO_NONE)) 223 isoverlay = 0; 224 else 225 isoverlay = 1; 226 227 /* Insure video is enabled */ 228 sc->sc_set_video(sc, 1); 229 230 if (isconsole) { 231 printf(" (console)\n"); 232 #ifdef RASTERCONSOLE 233 /* 234 * XXX rcons doesn't seem to work properly on the overlay 235 * XXX plane. This is a temporary kludge until someone 236 * XXX fixes it. 237 */ 238 if (!isoverlay) 239 fbrcons_init(fb); 240 #endif 241 } else 242 printf("\n"); 243 244 if (isoverlay) { 245 const char *ovnam; 246 247 switch (sc->sc_ovtype) { 248 case BWO_CGFOUR: 249 ovnam = "cgfour"; 250 break; 251 252 case BWO_CGEIGHT: 253 ovnam = "cgeight"; 254 break; 255 256 default: 257 ovnam = "unknown"; 258 break; 259 } 260 printf("%s: %s overlay plane\n", 261 device_xname(sc->sc_dev), ovnam); 262 } 263 264 /* 265 * If we're on an overlay plane of a color framebuffer, 266 * then we don't force the issue in fb_attach() because 267 * we'd like the color framebuffer to actually be the 268 * "console framebuffer". We're only around to speed 269 * up rconsole. 270 */ 271 if (isoverlay) 272 fb_attach(fb, 0); 273 else 274 fb_attach(fb, isconsole); 275 276 #if NWSDISPLAY > 0 277 sc->sc_width = fb->fb_type.fb_width; 278 sc->sc_stride = fb->fb_type.fb_width/8; 279 sc->sc_height = fb->fb_type.fb_height; 280 281 /* setup rasops and so on for wsdisplay */ 282 sc->sc_mode = WSDISPLAYIO_MODE_EMUL; 283 284 vcons_init(&sc->vd, sc, &bwtwo_defaultscreen, &bwtwo_accessops); 285 sc->vd.init_screen = bwtwo_init_screen; 286 287 if(isconsole && !isoverlay) { 288 /* we mess with bw2_console_screen only once */ 289 vcons_init_screen(&sc->vd, &bw2_console_screen, 1, 290 &defattr); 291 bw2_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; 292 293 bwtwo_defaultscreen.textops = &ri->ri_ops; 294 bwtwo_defaultscreen.capabilities = ri->ri_caps; 295 bwtwo_defaultscreen.nrows = ri->ri_rows; 296 bwtwo_defaultscreen.ncols = ri->ri_cols; 297 sc->vd.active = &bw2_console_screen; 298 wsdisplay_cnattach(&bwtwo_defaultscreen, ri, 0, 0, defattr); 299 } else { 300 /* 301 * we're not the console so we just clear the screen and don't 302 * set up any sort of text display 303 */ 304 if (bwtwo_defaultscreen.textops == NULL) { 305 /* 306 * ugly, but... 307 * we want the console settings to win, so we only 308 * touch anything when we find an untouched screen 309 * definition. In this case we fill it from fb to 310 * avoid problems in case no bwtwo is the console 311 */ 312 bwtwo_defaultscreen.textops = &ri->ri_ops; 313 bwtwo_defaultscreen.capabilities = ri->ri_caps; 314 bwtwo_defaultscreen.nrows = ri->ri_rows; 315 bwtwo_defaultscreen.ncols = ri->ri_cols; 316 } 317 } 318 319 aa.scrdata = &bwtwo_screenlist; 320 if (isoverlay) 321 aa.console = 0; 322 else 323 aa.console = isconsole; 324 aa.accessops = &bwtwo_accessops; 325 aa.accesscookie = &sc->vd; 326 config_found(sc->sc_dev, &aa, wsemuldisplaydevprint, CFARGS_NONE); 327 #endif 328 329 } 330 331 int 332 bwtwoopen(dev_t dev, int flags, int mode, struct lwp *l) 333 { 334 int unit = minor(dev); 335 336 if (device_lookup(&bwtwo_cd, unit) == NULL) 337 return (ENXIO); 338 339 return (0); 340 } 341 342 int 343 bwtwoioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) 344 { 345 struct bwtwo_softc *sc = device_lookup_private(&bwtwo_cd, minor(dev)); 346 347 switch (cmd) { 348 349 case FBIOGTYPE: 350 *(struct fbtype *)data = sc->sc_fb.fb_type; 351 break; 352 353 case FBIOGVIDEO: 354 *(int *)data = sc->sc_get_video(sc); 355 break; 356 357 case FBIOSVIDEO: 358 sc->sc_set_video(sc, (*(int *)data)); 359 break; 360 361 default: 362 return (ENOTTY); 363 } 364 return (0); 365 } 366 367 static void 368 bwtwounblank(device_t dev) 369 { 370 struct bwtwo_softc *sc = device_private(dev); 371 372 sc->sc_set_video(sc, 1); 373 } 374 375 /* 376 * Return the address that would map the given device at the given 377 * offset, allowing for the given protection, or return -1 for error. 378 */ 379 paddr_t 380 bwtwommap(dev_t dev, off_t off, int prot) 381 { 382 struct bwtwo_softc *sc = device_lookup_private(&bwtwo_cd, minor(dev)); 383 384 if (off & PGOFSET) 385 panic("bwtwommap"); 386 387 if (off >= sc->sc_fb.fb_type.fb_size) 388 return (-1); 389 390 return (bus_space_mmap(sc->sc_bustag, 391 sc->sc_paddr, sc->sc_pixeloffset + off, 392 prot, BUS_SPACE_MAP_LINEAR)); 393 } 394 395 #if NWSDISPLAY > 0 396 397 int 398 bwtwo_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, 399 struct lwp *l) 400 { 401 /* we'll probably need to add more stuff here */ 402 struct vcons_data *vd = v; 403 struct bwtwo_softc *sc = vd->cookie; 404 struct wsdisplay_fbinfo *wdf; 405 struct vcons_screen *ms = sc->vd.active; 406 struct rasops_info *ri = &ms->scr_ri; 407 switch (cmd) { 408 case WSDISPLAYIO_GTYPE: 409 *(u_int *)data = WSDISPLAY_TYPE_GENFB; 410 return 0; 411 case WSDISPLAYIO_GINFO: 412 wdf = (void *)data; 413 wdf->height = ri->ri_height; 414 wdf->width = ri->ri_width; 415 wdf->depth = ri->ri_depth; 416 wdf->cmsize = 0; 417 return 0; 418 419 case WSDISPLAYIO_GETCMAP: 420 return EINVAL; 421 case WSDISPLAYIO_PUTCMAP: 422 return EINVAL; 423 424 case WSDISPLAYIO_SMODE: 425 { 426 int new_mode = *(int*)data; 427 if (new_mode != sc->sc_mode) 428 { 429 sc->sc_mode = new_mode; 430 if(new_mode == WSDISPLAYIO_MODE_EMUL) 431 { 432 vcons_redraw_screen(ms); 433 } 434 } 435 } 436 return 0; 437 case WSDISPLAYIO_GET_FBINFO: 438 { 439 struct wsdisplayio_fbinfo *fbi = data; 440 441 return wsdisplayio_get_fbinfo(&ms->scr_ri, fbi); 442 } 443 } 444 return EPASSTHROUGH; 445 } 446 447 paddr_t 448 bwtwo_mmap(void *v, void *vs, off_t offset, int prot) 449 { 450 struct vcons_data *vd = v; 451 struct bwtwo_softc *sc = vd->cookie; 452 453 if (offset < 0) return -1; 454 if (offset >= sc->sc_fb.fb_type.fb_size) 455 return -1; 456 457 return bus_space_mmap(sc->sc_bustag, 458 sc->sc_paddr, sc->sc_pixeloffset + offset, 459 prot, BUS_SPACE_MAP_LINEAR); 460 } 461 462 void 463 bwtwo_init_screen(void *cookie, struct vcons_screen *scr, 464 int existing, long *defattr) 465 { 466 struct bwtwo_softc *sc = cookie; 467 struct rasops_info *ri = &scr->scr_ri; 468 char *bits; 469 470 ri->ri_depth = 1; 471 ri->ri_width = sc->sc_width; 472 ri->ri_height = sc->sc_height; 473 ri->ri_stride = sc->sc_stride; 474 ri->ri_flg = RI_CENTER; 475 476 ri->ri_bits = sc->sc_fb.fb_pixels; 477 478 /* 479 * Make sure that we set a maximum of 32 bits at a time, 480 * otherwise we'll see VME write errors if this is a P4 BW2. 481 */ 482 for (bits = (char *) ri->ri_bits; 483 bits < (char *) ri->ri_bits + ri->ri_stride * ri->ri_height; 484 bits += 4) 485 memset(bits, (*defattr >> 16) & 0xff, 4); 486 rasops_init(ri, 0, 0); 487 ri->ri_caps = 0; 488 rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight, 489 sc->sc_width / ri->ri_font->fontwidth); 490 491 ri->ri_hw = scr; 492 } 493 494 #endif /* NWSDISPLAY > 0 */ 495