1 /* $NetBSD: macfb.c,v 1.2 2000/02/14 07:01:47 scottr Exp $ */ 2 /* 3 * Copyright (c) 1998 Matt DeBergalis 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Matt DeBergalis 17 * 4. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include "opt_wsdisplay_compat.h" 33 #include "grf.h" 34 35 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/kernel.h> 40 #include <sys/device.h> 41 #include <sys/malloc.h> 42 43 #include <machine/cpu.h> 44 #include <machine/bus.h> 45 46 #include <machine/grfioctl.h> 47 #include <mac68k/nubus/nubus.h> 48 #include <mac68k/dev/grfvar.h> 49 #include <mac68k/dev/macfbvar.h> 50 #include <dev/wscons/wsconsio.h> 51 52 #include <dev/rcons/raster.h> 53 #include <dev/wscons/wscons_raster.h> 54 #include <dev/wscons/wsdisplayvar.h> 55 56 int macfb_match __P((struct device *, struct cfdata *, void *)); 57 void macfb_attach __P((struct device *, struct device *, void *)); 58 59 struct cfattach macfb_ca = { 60 sizeof(struct macfb_softc), 61 macfb_match, 62 macfb_attach, 63 }; 64 65 const struct wsdisplay_emulops macfb_emulops = { 66 rcons_cursor, 67 rcons_mapchar, 68 rcons_putchar, 69 rcons_copycols, 70 rcons_erasecols, 71 rcons_copyrows, 72 rcons_eraserows, 73 rcons_alloc_attr 74 }; 75 76 struct wsscreen_descr macfb_stdscreen = { 77 "std", 78 0, 0, /* will be filled in -- XXX shouldn't, it's global */ 79 &macfb_emulops, 80 0, 0, 81 WSSCREEN_REVERSE 82 }; 83 84 const struct wsscreen_descr *_macfb_scrlist[] = { 85 &macfb_stdscreen, 86 }; 87 88 const struct wsscreen_list macfb_screenlist = { 89 sizeof(_macfb_scrlist) / sizeof(struct wsscreen_descr *), 90 _macfb_scrlist 91 }; 92 93 static int macfb_ioctl __P((void *, u_long, caddr_t, int, struct proc *)); 94 static int macfb_mmap __P((void *, off_t, int)); 95 static int macfb_alloc_screen __P((void *, const struct wsscreen_descr *, 96 void **, int *, int *, long *)); 97 static void macfb_free_screen __P((void *, void *)); 98 static int macfb_show_screen __P((void *, void *, int, 99 void (*)(void *, int, int), void *)); 100 101 const struct wsdisplay_accessops macfb_accessops = { 102 macfb_ioctl, 103 macfb_mmap, 104 macfb_alloc_screen, 105 macfb_free_screen, 106 macfb_show_screen, 107 0 /* load_font */ 108 }; 109 110 void macfb_init __P((struct macfb_devconfig *)); 111 112 paddr_t macfb_consaddr; 113 static int macfb_is_console __P((paddr_t addr)); 114 #ifdef WSDISPLAY_COMPAT_ITEFONT 115 static void init_itefont __P((void)); 116 #endif /* WSDISPLAY_COMPAT_ITEFONT */ 117 118 static struct macfb_devconfig macfb_console_dc; 119 120 /* From Booter via locore */ 121 extern long videoaddr; 122 extern long videorowbytes; 123 extern long videobitdepth; 124 extern u_long videosize; 125 extern u_int32_t mac68k_vidlog; 126 extern u_int32_t mac68k_vidphys; 127 extern u_int32_t mac68k_vidlen; 128 129 static int 130 macfb_is_console(paddr_t addr) 131 { 132 return ((mac68k_machine.serial_console & 0x03) == 0 133 && (addr == macfb_consaddr)); 134 } 135 136 void 137 macfb_clear(dc) 138 struct macfb_devconfig *dc; 139 { 140 int i, rows; 141 142 /* clear the display */ 143 rows = dc->dc_ht; 144 for (i = 0; rows-- > 0; i += dc->dc_rowbytes) 145 memset((u_char *)dc->dc_vaddr + dc->dc_offset + i, 146 0, dc->dc_rowbytes); 147 } 148 149 void 150 macfb_init(dc) 151 struct macfb_devconfig *dc; 152 { 153 struct raster *rap; 154 struct rcons *rcp; 155 156 macfb_clear(dc); 157 158 #ifdef WSDISPLAY_COMPAT_ITEFONT 159 init_itefont(); 160 #endif /* WSDISPLAY_COMPAT_ITEFONT */ 161 162 rap = &dc->dc_raster; 163 rap->width = dc->dc_wid; 164 rap->height = dc->dc_ht; 165 rap->depth = dc->dc_depth; 166 rap->linelongs = dc->dc_rowbytes / sizeof(u_int32_t); 167 rap->pixels = (u_int32_t *)(dc->dc_vaddr + dc->dc_offset); 168 169 /* initialize the raster console blitter */ 170 rcp = &dc->dc_rcons; 171 rcp->rc_sp = rap; 172 rcp->rc_crow = rcp->rc_ccol = -1; 173 rcp->rc_crowp = &rcp->rc_crow; 174 rcp->rc_ccolp = &rcp->rc_ccol; 175 rcons_init(rcp, 128, 192); 176 177 macfb_stdscreen.nrows = dc->dc_rcons.rc_maxrow; 178 macfb_stdscreen.ncols = dc->dc_rcons.rc_maxcol; 179 } 180 181 int 182 macfb_match(parent, match, aux) 183 struct device *parent; 184 struct cfdata *match; 185 void *aux; 186 { 187 return (1); 188 } 189 190 void 191 macfb_attach(parent, self, aux) 192 struct device *parent; 193 struct device *self; 194 void *aux; 195 { 196 struct grfbus_attach_args *ga = aux; 197 struct grfmode *gm = ga->ga_grfmode; 198 struct macfb_softc *sc; 199 struct wsemuldisplaydev_attach_args waa; 200 int isconsole; 201 202 sc = (struct macfb_softc *)self; 203 204 printf("\n"); 205 206 isconsole = macfb_is_console(ga->ga_phys + ga->ga_grfmode->fboff); 207 208 if (isconsole) { 209 sc->sc_dc = &macfb_console_dc; 210 sc->nscreens = 1; 211 } else { 212 sc->sc_dc = malloc(sizeof(struct macfb_devconfig), M_DEVBUF, M_WAITOK); 213 sc->sc_dc->dc_vaddr = (vaddr_t)gm->fbbase; 214 sc->sc_dc->dc_paddr = ga->ga_phys; 215 sc->sc_dc->dc_size = gm->fbsize; 216 217 sc->sc_dc->dc_wid = gm->width; 218 sc->sc_dc->dc_ht = gm->height; 219 sc->sc_dc->dc_depth = gm->psize; 220 sc->sc_dc->dc_rowbytes = gm->rowbytes; 221 222 sc->sc_dc->dc_offset = gm->fboff; 223 224 macfb_init(sc->sc_dc); 225 226 sc->nscreens = 1; 227 } 228 229 /* initialize the raster */ 230 waa.console = isconsole; 231 waa.scrdata = &macfb_screenlist; 232 waa.accessops = &macfb_accessops; 233 waa.accesscookie = sc; 234 235 config_found(self, &waa, wsemuldisplaydevprint); 236 237 #if NGRF > 0 238 grf_attach(sc, self->dv_unit); 239 #endif 240 } 241 242 243 int 244 macfb_ioctl(v, cmd, data, flag, p) 245 void *v; 246 u_long cmd; 247 caddr_t data; 248 int flag; 249 struct proc *p; 250 { 251 struct macfb_softc *sc = v; 252 struct macfb_devconfig *dc = sc->sc_dc; 253 struct wsdisplay_fbinfo *wdf; 254 255 switch (cmd) { 256 case WSDISPLAYIO_GTYPE: 257 *(int *)data = dc->dc_type; 258 return 0; 259 260 case WSDISPLAYIO_GINFO: 261 wdf = (struct wsdisplay_fbinfo *)data; 262 wdf->height = dc->dc_raster.height; 263 wdf->width = dc->dc_raster.width; 264 wdf->depth = dc->dc_raster.depth; 265 wdf->cmsize = 256; 266 return 0; 267 268 case WSDISPLAYIO_GCURMAX: 269 case WSDISPLAYIO_GCURPOS: 270 case WSDISPLAYIO_GCURSOR: 271 case WSDISPLAYIO_GETCMAP: 272 case WSDISPLAYIO_GVIDEO: 273 case WSDISPLAYIO_PUTCMAP: 274 case WSDISPLAYIO_SCURPOS: 275 case WSDISPLAYIO_SCURSOR: 276 case WSDISPLAYIO_SVIDEO: 277 /* NONE of these operations are supported. */ 278 return ENOTTY; 279 } 280 281 return -1; 282 } 283 284 static int 285 macfb_mmap(v, offset, prot) 286 void *v; 287 off_t offset; 288 int prot; 289 { 290 struct macfb_softc *sc = v; 291 struct macfb_devconfig *dc = sc->sc_dc; 292 u_long addr; 293 294 if (offset >= 0 && 295 offset < m68k_round_page(dc->dc_rowbytes * dc->dc_ht)) 296 addr = m68k_btop(dc->dc_paddr + dc->dc_offset + offset); 297 else 298 addr = (-1); /* XXX bogus */ 299 300 return (int)addr; 301 } 302 303 int 304 macfb_alloc_screen(v, type, cookiep, curxp, curyp, defattrp) 305 void *v; 306 const struct wsscreen_descr *type; 307 void **cookiep; 308 int *curxp, *curyp; 309 long *defattrp; 310 { 311 struct macfb_softc *sc = v; 312 long defattr; 313 314 if (sc->nscreens > 0) 315 return (ENOMEM); 316 317 *cookiep = &sc->sc_dc->dc_rcons; /* one and only for now */ 318 *curxp = 0; 319 *curyp = 0; 320 rcons_alloc_attr(&sc->sc_dc->dc_rcons, 0, 0, 0, &defattr); 321 *defattrp = defattr; 322 sc->nscreens++; 323 return (0); 324 } 325 326 void 327 macfb_free_screen(v, cookie) 328 void *v; 329 void *cookie; 330 { 331 struct macfb_softc *sc = v; 332 333 if (sc->sc_dc == &macfb_console_dc) 334 panic("cfb_free_screen: console"); 335 336 sc->nscreens--; 337 } 338 339 int 340 macfb_show_screen(v, cookie, waitok, cb, cbarg) 341 void *v; 342 void *cookie; 343 int waitok; 344 void (*cb) __P((void *, int, int)); 345 void *cbarg; 346 { 347 return 0; 348 } 349 350 int 351 macfb_cnattach(addr) 352 paddr_t addr; 353 { 354 struct macfb_devconfig *dc = &macfb_console_dc; 355 long defattr; 356 357 dc->dc_vaddr = m68k_trunc_page(videoaddr); 358 dc->dc_paddr = m68k_trunc_page(mac68k_vidphys); 359 360 dc->dc_wid = videosize & 0xffff; 361 dc->dc_ht = (videosize >> 16) & 0xffff; 362 dc->dc_depth = videobitdepth; 363 dc->dc_rowbytes = videorowbytes; 364 365 dc->dc_size = (mac68k_vidlen > 0) ? 366 mac68k_vidlen : dc->dc_ht * dc->dc_rowbytes; 367 dc->dc_offset = m68k_page_offset(mac68k_vidphys); 368 369 /* set up the display */ 370 macfb_init(&macfb_console_dc); 371 372 rcons_alloc_attr(&dc->dc_rcons, 0, 0, 0, &defattr); 373 374 wsdisplay_cnattach(&macfb_stdscreen, &dc->dc_rcons, 375 0, 0, defattr); 376 377 macfb_consaddr = addr; 378 dc->isconsole = 1; 379 return (0); 380 } 381 382 #ifdef WSDISPLAY_COMPAT_ITEFONT 383 #include <mac68k/dev/6x10.h> 384 385 void 386 init_itefont() 387 { 388 static int itefont_initted = 0; 389 int i, j; 390 391 extern struct raster_font gallant19; /* XXX */ 392 393 if (itefont_initted) 394 return; 395 itefont_initted = 1; 396 397 /* XXX but we cannot use malloc here... */ 398 gallant19.width = 6; 399 gallant19.height = 10; 400 gallant19.ascent = 0; 401 402 for (i = 32; i < 128; i++) { 403 u_int *p; 404 405 if (gallant19.chars[i].r == NULL) 406 continue; 407 408 gallant19.chars[i].r->width = 6; 409 gallant19.chars[i].r->height = 10; 410 p = gallant19.chars[i].r->pixels; 411 412 for (j = 0; j < 10; j++) 413 *p++ = Font6x10[i * 10 + j] << 26; 414 } 415 } 416 #endif /* WSDISPLAY_COMPAT_ITEFONT */ 417