1 /* $NetBSD: cgfour.c,v 1.42 2006/03/29 04:16:47 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 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * Copyright (c) 1992, 1993 41 * The Regents of the University of California. All rights reserved. 42 * 43 * This software was developed by the Computer Systems Engineering group 44 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 45 * contributed to Berkeley. 46 * 47 * All advertising materials mentioning features or use of this software 48 * must display the following acknowledgement: 49 * This product includes software developed by the University of 50 * California, Lawrence Berkeley Laboratory. 51 * 52 * Redistribution and use in source and binary forms, with or without 53 * modification, are permitted provided that the following conditions 54 * are met: 55 * 1. Redistributions of source code must retain the above copyright 56 * notice, this list of conditions and the following disclaimer. 57 * 2. Redistributions in binary form must reproduce the above copyright 58 * notice, this list of conditions and the following disclaimer in the 59 * documentation and/or other materials provided with the distribution. 60 * 3. Neither the name of the University nor the names of its contributors 61 * may be used to endorse or promote products derived from this software 62 * without specific prior written permission. 63 * 64 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 65 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 66 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 67 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 68 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 69 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 70 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 71 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 72 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 73 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 74 * SUCH DAMAGE. 75 * 76 * from @(#)cgthree.c 8.2 (Berkeley) 10/30/93 77 */ 78 79 /* 80 * Copyright (c) 1995 Theo de Raadt. All rights reserved. 81 * 82 * Redistribution and use in source and binary forms, with or without 83 * modification, are permitted provided that the following conditions 84 * are met: 85 * 1. Redistributions of source code must retain the above copyright 86 * notice, this list of conditions and the following disclaimer. 87 * 2. Redistributions in binary form must reproduce the above copyright 88 * notice, this list of conditions and the following disclaimer in the 89 * documentation and/or other materials provided with the distribution. 90 * 91 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 92 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 93 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 94 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 95 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 96 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 97 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 98 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 99 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 100 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 101 */ 102 103 /* 104 * color display (cgfour) driver. 105 * 106 * Does not handle interrupts, even though they can occur. 107 * 108 * XXX should defer colormap updates to vertical retrace interrupts 109 */ 110 111 #include <sys/cdefs.h> 112 __KERNEL_RCSID(0, "$NetBSD: cgfour.c,v 1.42 2006/03/29 04:16:47 thorpej Exp $"); 113 114 #include <sys/param.h> 115 #include <sys/systm.h> 116 #include <sys/buf.h> 117 #include <sys/device.h> 118 #include <sys/ioctl.h> 119 #include <sys/malloc.h> 120 #include <sys/mman.h> 121 #include <sys/tty.h> 122 #include <sys/conf.h> 123 124 #include <machine/autoconf.h> 125 #include <machine/eeprom.h> 126 127 #include <dev/sun/fbio.h> 128 #include <dev/sun/fbvar.h> 129 #include <dev/sun/btreg.h> 130 #include <dev/sun/btvar.h> 131 #include <dev/sun/pfourreg.h> 132 133 /* per-display variables */ 134 struct cgfour_softc { 135 struct device sc_dev; /* base device */ 136 struct fbdevice sc_fb; /* frame buffer device */ 137 bus_space_tag_t sc_bustag; 138 bus_addr_t sc_paddr; /* phys address for device mmap() */ 139 140 volatile struct fbcontrol *sc_fbc; /* Brooktree registers */ 141 union bt_cmap sc_cmap; /* Brooktree color map */ 142 }; 143 144 /* autoconfiguration driver */ 145 static int cgfourmatch(struct device *, struct cfdata *, void *); 146 static void cgfourattach(struct device *, struct device *, void *); 147 148 #if defined(SUN4) 149 static void cgfourunblank(struct device *); 150 #endif 151 152 static int cg4_pfour_probe(void *, void *); 153 154 CFATTACH_DECL(cgfour, sizeof(struct cgfour_softc), 155 cgfourmatch, cgfourattach, NULL, NULL); 156 157 extern struct cfdriver cgfour_cd; 158 159 dev_type_open(cgfouropen); 160 dev_type_ioctl(cgfourioctl); 161 dev_type_mmap(cgfourmmap); 162 163 const struct cdevsw cgfour_cdevsw = { 164 cgfouropen, nullclose, noread, nowrite, cgfourioctl, 165 nostop, notty, nopoll, cgfourmmap, nokqfilter, 166 }; 167 168 #if defined(SUN4) 169 /* frame buffer generic driver */ 170 static struct fbdriver cgfourfbdriver = { 171 cgfourunblank, cgfouropen, nullclose, cgfourioctl, nopoll, 172 cgfourmmap, nokqfilter 173 }; 174 175 static void cgfourloadcmap(struct cgfour_softc *, int, int); 176 static int cgfour_get_video(struct cgfour_softc *); 177 static void cgfour_set_video(struct cgfour_softc *, int); 178 #endif 179 180 /* 181 * Match a cgfour. 182 */ 183 static int 184 cgfourmatch(struct device *parent, struct cfdata *cf, void *aux) 185 { 186 union obio_attach_args *uoba = aux; 187 struct obio4_attach_args *oba; 188 189 if (uoba->uoba_isobio4 == 0) 190 return (0); 191 192 oba = &uoba->uoba_oba4; 193 return (bus_space_probe(oba->oba_bustag, oba->oba_paddr, 194 4, /* probe size */ 195 0, /* offset */ 196 0, /* flags */ 197 cg4_pfour_probe, NULL)); 198 } 199 200 static int 201 cg4_pfour_probe(void *vaddr, void *arg) 202 { 203 204 return (fb_pfour_id(vaddr) == PFOUR_ID_COLOR8P1); 205 } 206 207 /* 208 * Attach a display. We need to notice if it is the console, too. 209 */ 210 static void 211 cgfourattach(struct device *parent, struct device *self, void *aux) 212 { 213 #if defined(SUN4) 214 struct cgfour_softc *sc = (struct cgfour_softc *)self; 215 union obio_attach_args *uoba = aux; 216 struct obio4_attach_args *oba = &uoba->uoba_oba4; 217 bus_space_handle_t bh; 218 volatile struct bt_regs *bt; 219 struct fbdevice *fb = &sc->sc_fb; 220 int ramsize, i, isconsole; 221 222 sc->sc_bustag = oba->oba_bustag; 223 sc->sc_paddr = (bus_addr_t)oba->oba_paddr; 224 225 /* Map the pfour register. */ 226 if (bus_space_map(oba->oba_bustag, oba->oba_paddr, 227 sizeof(uint32_t), 228 BUS_SPACE_MAP_LINEAR, 229 &bh) != 0) { 230 printf("%s: cannot map control registers\n", self->dv_xname); 231 return; 232 } 233 fb->fb_pfour = (volatile uint32_t *)bh; 234 235 fb->fb_driver = &cgfourfbdriver; 236 fb->fb_device = &sc->sc_dev; 237 fb->fb_type.fb_type = FBTYPE_SUN4COLOR; 238 fb->fb_flags = device_cfdata(&sc->sc_dev)->cf_flags & FB_USERMASK; 239 fb->fb_flags |= FB_PFOUR; 240 241 ramsize = PFOUR_COLOR_OFF_END - PFOUR_COLOR_OFF_OVERLAY; 242 243 fb->fb_type.fb_depth = 8; 244 fb_setsize_eeprom(fb, fb->fb_type.fb_depth, 1152, 900); 245 246 fb->fb_type.fb_cmsize = 256; 247 fb->fb_type.fb_size = ramsize; 248 printf(": cgfour/p4, %d x %d", 249 fb->fb_type.fb_width, fb->fb_type.fb_height); 250 251 isconsole = 0; 252 253 if (CPU_ISSUN4) { 254 struct eeprom *eep = (struct eeprom *)eeprom_va; 255 256 /* 257 * Assume this is the console if there's no eeprom info 258 * to be found. 259 */ 260 if (eep == NULL || eep->eeConsole == EE_CONS_P4OPT) 261 isconsole = fb_is_console(0); 262 } 263 264 #if 0 265 /* 266 * We don't do any of the console handling here. Instead, 267 * we let the bwtwo driver pick up the overlay plane and 268 * use it instead. Rconsole should have better performance 269 * with the 1-bit depth. 270 * -- Jason R. Thorpe <thorpej@NetBSD.org> 271 */ 272 273 /* 274 * When the ROM has mapped in a cgfour display, the address 275 * maps only the video RAM, so in any case we have to map the 276 * registers ourselves. We only need the video RAM if we are 277 * going to print characters via rconsole. 278 */ 279 280 if (isconsole) { 281 /* XXX this is kind of a waste */ 282 fb->fb_pixels = mapiodev(ca->ca_ra.ra_reg, 283 PFOUR_COLOR_OFF_OVERLAY, ramsize); 284 } 285 #endif 286 287 /* Map the Brooktree. */ 288 if (bus_space_map(oba->oba_bustag, 289 oba->oba_paddr + PFOUR_COLOR_OFF_CMAP, 290 sizeof(struct fbcontrol), 291 BUS_SPACE_MAP_LINEAR, 292 &bh) != 0) { 293 printf("%s: cannot map control registers\n", self->dv_xname); 294 return; 295 } 296 sc->sc_fbc = (volatile struct fbcontrol *)bh; 297 298 /* grab initial (current) color map */ 299 bt = &sc->sc_fbc->fbc_dac; 300 bt->bt_addr = 0; 301 for (i = 0; i < 256 * 3 / 4; i++) 302 ((char *)&sc->sc_cmap)[i] = bt->bt_cmap >> 24; 303 304 BT_INIT(bt, 24); 305 306 #if 0 /* See above. */ 307 if (isconsole) { 308 printf(" (console)\n"); 309 #if defined(RASTERCONSOLE) && 0 /* XXX been told it doesn't work well. */ 310 fbrcons_init(fb); 311 #endif 312 } else 313 #endif /* 0 */ 314 printf("\n"); 315 316 /* 317 * Even though we're not using rconsole, we'd still like 318 * to notice if we're the console framebuffer. 319 */ 320 fb_attach(fb, isconsole); 321 #endif /* SUN4 */ 322 } 323 324 int 325 cgfouropen(dev_t dev, int flags, int mode, struct lwp *l) 326 { 327 int unit = minor(dev); 328 329 if (unit >= cgfour_cd.cd_ndevs || cgfour_cd.cd_devs[unit] == NULL) 330 return (ENXIO); 331 return (0); 332 } 333 334 int 335 cgfourioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct lwp *l) 336 { 337 #if defined(SUN4) 338 struct cgfour_softc *sc = cgfour_cd.cd_devs[minor(dev)]; 339 struct fbgattr *fba; 340 int error; 341 342 switch (cmd) { 343 344 case FBIOGTYPE: 345 *(struct fbtype *)data = sc->sc_fb.fb_type; 346 break; 347 348 case FBIOGATTR: 349 fba = (struct fbgattr *)data; 350 fba->real_type = sc->sc_fb.fb_type.fb_type; 351 fba->owner = 0; /* XXX ??? */ 352 fba->fbtype = sc->sc_fb.fb_type; 353 fba->sattr.flags = 0; 354 fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type; 355 fba->sattr.dev_specific[0] = -1; 356 fba->emu_types[0] = sc->sc_fb.fb_type.fb_type; 357 fba->emu_types[1] = -1; 358 break; 359 360 case FBIOGETCMAP: 361 #define p ((struct fbcmap *)data) 362 return (bt_getcmap(p, &sc->sc_cmap, 256, 1)); 363 364 case FBIOPUTCMAP: 365 /* copy to software map */ 366 error = bt_putcmap(p, &sc->sc_cmap, 256, 1); 367 if (error) 368 return (error); 369 /* now blast them into the chip */ 370 /* XXX should use retrace interrupt */ 371 cgfourloadcmap(sc, p->index, p->count); 372 #undef p 373 break; 374 375 case FBIOGVIDEO: 376 *(int *)data = cgfour_get_video(sc); 377 break; 378 379 case FBIOSVIDEO: 380 cgfour_set_video(sc, *(int *)data); 381 break; 382 383 default: 384 return (ENOTTY); 385 } 386 #endif /* SUN4 */ 387 388 return (0); 389 } 390 391 /* 392 * Return the address that would map the given device at the given 393 * offset, allowing for the given protection, or return -1 for error. 394 * 395 * the cg4 maps it's overlay plane for 128K, followed by the enable 396 * plane for 128K, followed by the colour plane (for as much colour 397 * as their is.) 398 * 399 * As well, mapping at an offset of 0x04000000 causes the cg4 to map 400 * only it's colour plane, at 0. 401 */ 402 paddr_t 403 cgfourmmap(dev_t dev, off_t off, int prot) 404 { 405 struct cgfour_softc *sc = cgfour_cd.cd_devs[minor(dev)]; 406 off_t poff; 407 408 #define START_ENABLE (128*1024) 409 #define START_COLOR ((128*1024) + (128*1024)) 410 #define COLOR_SIZE (sc->sc_fb.fb_type.fb_width * \ 411 sc->sc_fb.fb_type.fb_height) 412 #define END_COLOR (START_COLOR + COLOR_SIZE) 413 #define NOOVERLAY (0x04000000) 414 415 if (off & PGOFSET) 416 panic("cgfourmap"); 417 418 if (off < 0) 419 return (-1); 420 else if ((u_int)off >= NOOVERLAY) { 421 off -= NOOVERLAY; 422 423 /* 424 * X11 maps a huge chunk of the frame buffer; far more than 425 * there really is. We compensate by double-mapping the 426 * first page for as many other pages as it wants 427 */ 428 while ((u_int)off >= COLOR_SIZE) 429 off -= COLOR_SIZE; /* XXX thorpej ??? */ 430 431 poff = off + PFOUR_COLOR_OFF_COLOR; 432 } else if ((u_int)off < START_ENABLE) { 433 /* 434 * in overlay plane 435 */ 436 poff = PFOUR_COLOR_OFF_OVERLAY + off; 437 } else if ((u_int)off < START_COLOR) { 438 /* 439 * in enable plane 440 */ 441 poff = (off - START_ENABLE) + PFOUR_COLOR_OFF_ENABLE; 442 } else if ((u_int)off < sc->sc_fb.fb_type.fb_size) { 443 /* 444 * in colour plane 445 */ 446 poff = (off - START_COLOR) + PFOUR_COLOR_OFF_COLOR; 447 } else 448 return (-1); 449 450 return (bus_space_mmap(sc->sc_bustag, 451 sc->sc_paddr, poff, 452 prot, BUS_SPACE_MAP_LINEAR)); 453 } 454 455 #if defined(SUN4) 456 /* 457 * Undo the effect of an FBIOSVIDEO that turns the video off. 458 */ 459 static void 460 cgfourunblank(struct device *dev) 461 { 462 463 cgfour_set_video((struct cgfour_softc *)dev, 1); 464 } 465 466 static int 467 cgfour_get_video(struct cgfour_softc *sc) 468 { 469 470 return (fb_pfour_get_video(&sc->sc_fb)); 471 } 472 473 static void 474 cgfour_set_video(struct cgfour_softc *sc, int enable) 475 { 476 477 fb_pfour_set_video(&sc->sc_fb, enable); 478 } 479 480 /* 481 * Load a subset of the current (new) colormap into the Brooktree DAC. 482 */ 483 static void 484 cgfourloadcmap(struct cgfour_softc *sc, int start, int ncolors) 485 { 486 volatile struct bt_regs *bt; 487 u_int *ip, i; 488 int count; 489 490 ip = &sc->sc_cmap.cm_chip[BT_D4M3(start)]; /* start/4 * 3 */ 491 count = BT_D4M3(start + ncolors - 1) - BT_D4M3(start) + 3; 492 bt = &sc->sc_fbc->fbc_dac; 493 bt->bt_addr = BT_D4M4(start) << 24; 494 while (--count >= 0) { 495 i = *ip++; 496 /* hardware that makes one want to pound boards with hammers */ 497 bt->bt_cmap = i; 498 bt->bt_cmap = i << 8; 499 bt->bt_cmap = i << 16; 500 bt->bt_cmap = i << 24; 501 } 502 } 503 #endif /* SUN4 */ 504