1 /* $NetBSD: nextdisplay.c,v 1.2 1999/03/24 23:15:52 dbj Exp $ */ 2 3 /* 4 * Copyright (c) 1998 Matt DeBergalis 5 * All rights reserved. 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 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Matt DeBergalis 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/kernel.h> 38 #include <sys/device.h> 39 #include <sys/malloc.h> 40 41 #include <machine/cpu.h> 42 #include <machine/bus.h> 43 44 #include <next68k/next68k/nextrom.h> 45 46 #include <next68k/dev/nextdisplayvar.h> 47 #include <dev/wscons/wsconsio.h> 48 49 #include <dev/rcons/raster.h> 50 #include <dev/wscons/wscons_raster.h> 51 #include <dev/wscons/wsdisplayvar.h> 52 53 int nextdisplay_match __P((struct device *, struct cfdata *, void *)); 54 void nextdisplay_attach __P((struct device *, struct device *, void *)); 55 56 struct cfattach nextdisplay_ca = { 57 sizeof(struct nextdisplay_softc), 58 nextdisplay_match, 59 nextdisplay_attach, 60 }; 61 62 const struct wsdisplay_emulops nextdisplay_mono_emulops = { 63 rcons_cursor, 64 rcons_mapchar, 65 rcons_putchar, 66 rcons_copycols, 67 rcons_erasecols, 68 rcons_copyrows, 69 rcons_eraserows, 70 rcons_alloc_attr 71 }; 72 73 struct wsscreen_descr nextdisplay_mono = { 74 "mono", 75 0, 0, /* will be filled in -- XXX shouldn't, it's global */ 76 &nextdisplay_mono_emulops, 77 0, 0 78 }; 79 80 struct wsscreen_descr nextdisplay_color = { 81 "color", 82 0, 0, /* again, filled in */ 83 &nextdisplay_mono_emulops, 84 0, 0 85 }; 86 87 const struct wsscreen_descr *_nextdisplay_scrlist_mono[] = { 88 &nextdisplay_mono, 89 }; 90 91 const struct wsscreen_descr *_nextdisplay_scrlist_color[] = { 92 &nextdisplay_color, 93 }; 94 95 const struct wsscreen_list nextdisplay_screenlist_mono = { 96 sizeof(_nextdisplay_scrlist_mono) / sizeof(struct wsscreen_descr *), 97 _nextdisplay_scrlist_mono 98 }; 99 100 const struct wsscreen_list nextdisplay_screenlist_color = { 101 sizeof(_nextdisplay_scrlist_color) / sizeof(struct wsscreen_descr *), 102 _nextdisplay_scrlist_color 103 }; 104 105 static int nextdisplay_ioctl __P((void *, u_long, caddr_t, int, struct proc *)); 106 static int nextdisplay_mmap __P((void *, off_t, int)); 107 static int nextdisplay_alloc_screen __P((void *, const struct wsscreen_descr *, 108 void **, int *, int *, long *)); 109 static void nextdisplay_free_screen __P((void *, void *)); 110 static void nextdisplay_show_screen __P((void *, void *)); 111 static int nextdisplay_load_font __P((void *, void *, struct wsdisplay_font *)); 112 113 const struct wsdisplay_accessops nextdisplay_accessops = { 114 nextdisplay_ioctl, 115 nextdisplay_mmap, 116 nextdisplay_alloc_screen, 117 nextdisplay_free_screen, 118 nextdisplay_show_screen, 119 nextdisplay_load_font 120 }; 121 122 void nextdisplay_init(struct nextdisplay_config *, int); 123 124 paddr_t nextdisplay_consaddr; 125 static int nextdisplay_is_console __P((paddr_t addr)); 126 127 static struct nextdisplay_config nextdisplay_console_dc; 128 129 static int 130 nextdisplay_is_console(paddr_t addr) 131 { 132 return (nextdisplay_console_dc.isconsole 133 && (addr == nextdisplay_consaddr)); 134 } 135 136 int 137 nextdisplay_match(parent, match, aux) 138 struct device *parent; 139 struct cfdata *match; 140 void *aux; 141 { 142 if ((rom_machine_type == NeXT_WARP9) 143 || (rom_machine_type == NeXT_X15)) 144 return (1); 145 else 146 return (0); 147 } 148 149 void 150 nextdisplay_init(dc, color) 151 struct nextdisplay_config *dc; 152 int color; 153 { 154 struct raster *rap; 155 struct rcons *rcp; 156 paddr_t addr; 157 int i; 158 159 /* printf("in nextdisplay_init\n"); */ 160 161 if (color) 162 addr = (paddr_t)colorbase; 163 else 164 addr = (paddr_t)monobase; 165 166 dc->dc_vaddr = addr; 167 dc->dc_paddr = color ? COLORP(addr) : MONOP(addr); 168 dc->dc_size = color ? NEXT_P_C16_VIDEOSIZE : NEXT_P_VIDEOSIZE; 169 170 dc->dc_wid = 1152; /* XXX color */ 171 dc->dc_ht = 832; /* XXX color */ 172 dc->dc_depth = color ? 8 : 2; 173 dc->dc_rowbytes = dc->dc_wid * dc->dc_depth / 8; 174 175 dc->dc_videobase = dc->dc_vaddr; 176 177 #if 0 178 printf("intiobase at: %08x\n", intiobase); 179 printf("intiolimit at: %08x\n", intiolimit); 180 printf("videobase at: %08x\n", color ? colorbase : monobase); 181 printf("videolimit at: %08x\n", color ? colorlimit : monolimit); 182 183 printf("virtual fb at: %08x\n", dc->dc_vaddr); 184 printf("physical fb at: %08x\n", dc->dc_paddr); 185 printf("fb size: %08x\n", dc->dc_size); 186 187 printf("dc_wid: %08x\n", dc->dc_wid); 188 printf("dc_ht: %08x\n", dc->dc_ht); 189 printf("dc_depth: %08x\n", dc->dc_depth); 190 printf("dc_rowbytes: %08x\n", dc->dc_rowbytes); 191 printf("dc_videobase: %08x\n", dc->dc_videobase); 192 #endif 193 194 /* clear the screen */ 195 for (i = 0; i < dc->dc_ht * dc->dc_rowbytes; i += sizeof(u_int32_t)) 196 *(u_int32_t *)(dc->dc_videobase + i) = 0xffffffff; 197 198 rap = &dc->dc_raster; 199 rap->width = dc->dc_wid; 200 rap->height = dc->dc_ht; 201 rap->depth = color ? 8 : 2; 202 rap->linelongs = dc->dc_rowbytes / sizeof(u_int32_t); 203 rap->pixels = (u_int32_t *)dc->dc_videobase; 204 205 /* initialize the raster console blitter */ 206 rcp = &dc->dc_rcons; 207 rcp->rc_sp = rap; 208 rcp->rc_crow = rcp->rc_ccol = -1; 209 rcp->rc_crowp = &rcp->rc_crow; 210 rcp->rc_ccolp = &rcp->rc_ccol; 211 rcons_init(rcp, 34, 80); 212 213 if (color) { 214 nextdisplay_color.nrows = dc->dc_rcons.rc_maxrow; 215 nextdisplay_color.ncols = dc->dc_rcons.rc_maxcol; 216 } else { 217 nextdisplay_mono.nrows = dc->dc_rcons.rc_maxrow; 218 nextdisplay_mono.ncols = dc->dc_rcons.rc_maxcol; 219 } 220 } 221 222 void 223 nextdisplay_attach(parent, self, aux) 224 struct device *parent; 225 struct device *self; 226 void *aux; 227 { 228 struct nextdisplay_softc *sc; 229 struct wsemuldisplaydev_attach_args waa; 230 int isconsole; 231 int iscolor; 232 paddr_t addr; 233 234 sc = (struct nextdisplay_softc *)self; 235 236 if (rom_machine_type == NeXT_WARP9C) { 237 iscolor = 1; 238 addr = (paddr_t)colorbase; 239 } else { 240 iscolor = 0; 241 addr = (paddr_t)monobase; 242 } 243 244 isconsole = nextdisplay_is_console(addr); 245 246 if (isconsole) { 247 sc->sc_dc = &nextdisplay_console_dc; 248 sc->nscreens = 1; 249 } else { 250 sc->sc_dc = (struct nextdisplay_config *) 251 malloc(sizeof(struct nextdisplay_config), M_DEVBUF, M_WAITOK); 252 nextdisplay_init(sc->sc_dc, iscolor); 253 } 254 255 printf(": %d x %d, %dbpp\n", sc->sc_dc->dc_wid, sc->sc_dc->dc_ht, 256 sc->sc_dc->dc_depth); 257 258 /* initialize the raster */ 259 waa.console = isconsole; 260 waa.scrdata = iscolor ? &nextdisplay_screenlist_color : &nextdisplay_screenlist_mono; 261 waa.accessops = &nextdisplay_accessops; 262 waa.accesscookie = sc; 263 #if 0 264 printf("nextdisplay: access cookie is %p\n", sc); 265 #endif 266 config_found(self, &waa, wsemuldisplaydevprint); 267 } 268 269 270 int 271 nextdisplay_ioctl(v, cmd, data, flag, p) 272 void *v; 273 u_long cmd; 274 caddr_t data; 275 int flag; 276 struct proc *p; 277 { 278 struct nextdisplay_softc *sc = v; 279 struct nextdisplay_config *dc = sc->sc_dc; 280 281 switch (cmd) { 282 case WSDISPLAYIO_GTYPE: 283 *(int *)data = dc->dc_type; 284 return 0; 285 286 case WSDISPLAYIO_SCURSOR: 287 printf("nextdisplay_ioctl: wsdisplayio_scursor\n"); 288 return ENOTTY; 289 290 case WSDISPLAYIO_SCURPOS: 291 printf("nextdisplay_ioctl: wsdisplayio_scurpos\n"); 292 return ENOTTY; 293 294 case WSDISPLAYIO_GINFO: 295 case WSDISPLAYIO_GETCMAP: 296 case WSDISPLAYIO_PUTCMAP: 297 case WSDISPLAYIO_GVIDEO: 298 case WSDISPLAYIO_SVIDEO: 299 case WSDISPLAYIO_GCURPOS: 300 case WSDISPLAYIO_GCURMAX: 301 case WSDISPLAYIO_GCURSOR: 302 printf("nextdisplay_ioctl: listed but unsupported ioctl\n"); 303 return ENOTTY; 304 } 305 306 return ENOTTY; 307 } 308 309 static int 310 nextdisplay_mmap(v, offset, prot) 311 void *v; 312 off_t offset; 313 int prot; 314 { 315 316 /* XXX */ 317 printf("nextdisplay_mmap: failed\n"); 318 return -1; 319 } 320 321 int 322 nextdisplay_alloc_screen(v, type, cookiep, curxp, curyp, defattrp) 323 void *v; 324 const struct wsscreen_descr *type; 325 void **cookiep; 326 int *curxp, *curyp; 327 long *defattrp; 328 { 329 struct nextdisplay_softc *sc = v; 330 long defattr; 331 332 /* only allow one screen */ 333 if (sc->nscreens > 0) 334 return (ENOMEM); 335 336 *cookiep = &sc->sc_dc->dc_rcons; /* one and only for now */ 337 *curxp = 0; 338 *curyp = 0; 339 rcons_alloc_attr(&sc->sc_dc->dc_rcons, 0, 0, 340 WSATTR_REVERSE, &defattr); 341 *defattrp = defattr; 342 sc->nscreens++; 343 #if 0 344 printf("nextdisplay: allocating screen\n"); 345 #endif 346 return (0); 347 } 348 349 void 350 nextdisplay_free_screen(v, cookie) 351 void *v; 352 void *cookie; 353 { 354 struct nextdisplay_softc *sc = v; 355 356 if (sc->sc_dc == &nextdisplay_console_dc) 357 panic("nextdisplay_free_screen: console"); 358 359 sc->nscreens--; 360 } 361 362 void 363 nextdisplay_show_screen(v, cookie) 364 void *v; 365 void *cookie; 366 { 367 } 368 369 static int 370 nextdisplay_load_font(v, cookie, font) 371 void *v; 372 void *cookie; 373 struct wsdisplay_font *font; 374 { 375 return (EINVAL); 376 } 377 378 int 379 nextdisplay_cnattach(void) 380 { 381 struct nextdisplay_config *dc = &nextdisplay_console_dc; 382 long defattr; 383 int iscolor; 384 385 if (rom_machine_type == NeXT_WARP9C) { 386 iscolor = 1; 387 nextdisplay_consaddr = (paddr_t)colorbase; 388 } else { 389 iscolor = 0; 390 nextdisplay_consaddr = (paddr_t)monobase; 391 } 392 393 /* set up the display */ 394 nextdisplay_init(&nextdisplay_console_dc, iscolor); 395 396 rcons_alloc_attr(&dc->dc_rcons, 0, 0, WSATTR_REVERSE, &defattr); 397 398 wsdisplay_cnattach(iscolor ? &nextdisplay_color : &nextdisplay_mono, 399 &dc->dc_rcons, 0, 0, defattr); 400 401 dc->isconsole = 1; 402 return (0); 403 } 404