Home | History | Annotate | Line # | Download | only in dev
nextdisplay.c revision 1.12
      1 /* $NetBSD: nextdisplay.c,v 1.12 2002/10/02 04:22:53 thorpej 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/bus.h>
     42 #include <machine/cpu.h>
     43 
     44 #include <next68k/next68k/nextrom.h>
     45 
     46 #include <next68k/dev/intiovar.h>
     47 #include <next68k/dev/nextdisplayvar.h>
     48 #include <dev/wscons/wsconsio.h>
     49 
     50 #include <dev/rcons/raster.h>
     51 #include <dev/wscons/wscons_raster.h>
     52 #include <dev/wscons/wsdisplayvar.h>
     53 
     54 extern int turbo;
     55 
     56 int nextdisplay_match __P((struct device *, struct cfdata *, void *));
     57 void nextdisplay_attach __P((struct device *, struct device *, void *));
     58 
     59 CFATTACH_DECL(nextdisplay, sizeof(struct nextdisplay_softc),
     60     nextdisplay_match, nextdisplay_attach, NULL, NULL);
     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_allocattr
     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 paddr_t	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 int	nextdisplay_show_screen __P((void *, void *, int,
    111 					     void (*) (void *, int, int), void *));
    112 static int	nextdisplay_load_font __P((void *, void *, struct wsdisplay_font *));
    113 
    114 const struct wsdisplay_accessops nextdisplay_accessops = {
    115 	nextdisplay_ioctl,
    116 	nextdisplay_mmap,
    117 	nextdisplay_alloc_screen,
    118 	nextdisplay_free_screen,
    119 	nextdisplay_show_screen,
    120 	nextdisplay_load_font
    121 };
    122 
    123 void nextdisplay_init(struct nextdisplay_config *, int);
    124 
    125 paddr_t nextdisplay_consaddr;
    126 static int nextdisplay_is_console __P((paddr_t addr));
    127 
    128 static struct nextdisplay_config nextdisplay_console_dc;
    129 
    130 static int
    131 nextdisplay_is_console(paddr_t addr)
    132 {
    133 	return (nextdisplay_console_dc.isconsole
    134 			&& (addr == nextdisplay_consaddr));
    135 }
    136 
    137 int
    138 nextdisplay_match(parent, match, aux)
    139 	struct device *parent;
    140 	struct cfdata *match;
    141 	void *aux;
    142 {
    143 	if ((rom_machine_type == NeXT_WARP9)
    144 	    || (rom_machine_type == NeXT_X15)
    145 	    || (rom_machine_type == NeXT_WARP9C)
    146 	    || (rom_machine_type == NeXT_TURBO_MONO)
    147 	    || (rom_machine_type == NeXT_TURBO_COLOR))
    148 		return (1);
    149 	else
    150 		return (0);
    151 }
    152 
    153 void
    154 nextdisplay_init(dc, color)
    155 	struct nextdisplay_config *dc;
    156 	int color;
    157 {
    158 	struct raster *rap;
    159 	struct rcons *rcp;
    160 	paddr_t addr;
    161 	int i;
    162 
    163 	/* printf("in nextdisplay_init\n"); */
    164 
    165 	if (color)
    166 		addr = (paddr_t)colorbase;
    167 	else
    168 		addr = (paddr_t)monobase;
    169 
    170 	dc->dc_vaddr = addr;
    171 	dc->dc_paddr = color ? COLORP(addr) : MONOP(addr);
    172 	dc->dc_size = color ? NEXT_P_C16_VIDEOSIZE : NEXT_P_VIDEOSIZE;
    173 
    174 	dc->dc_wid = 1120;
    175 	dc->dc_ht = 832;
    176 	dc->dc_depth = color ? 16 : 2;
    177 	dc->dc_rowbytes = (turbo ? 1120 : 1152) * dc->dc_depth / 8;
    178 
    179 	dc->dc_videobase = dc->dc_vaddr;
    180 
    181 #if 0
    182 	printf("intiobase at: %08x\n", intiobase);
    183 	printf("intiolimit at: %08x\n", intiolimit);
    184 	printf("videobase at: %08x\n", color ? colorbase : monobase);
    185 	printf("videolimit at: %08x\n", color ? colorlimit : monolimit);
    186 
    187 	printf("virtual fb at: %08x\n", dc->dc_vaddr);
    188 	printf("physical fb at: %08x\n", dc->dc_paddr);
    189 	printf("fb size: %08x\n", dc->dc_size);
    190 
    191 	printf("dc_wid: %08x\n", dc->dc_wid);
    192 	printf("dc_ht: %08x\n", dc->dc_ht);
    193 	printf("dc_depth: %08x\n", dc->dc_depth);
    194 	printf("dc_rowbytes: %08x\n", dc->dc_rowbytes);
    195 	printf("dc_videobase: %08x\n", dc->dc_videobase);
    196 #endif
    197 
    198 	/* clear the screen */
    199 	for (i = 0; i < dc->dc_ht * dc->dc_rowbytes; i += sizeof(u_int32_t))
    200 		*(u_int32_t *)(dc->dc_videobase + i) =
    201 			(color ? 0x0 : 0xffffffff);
    202 
    203 	printf("done clearing\n");
    204 
    205 	rap = &dc->dc_raster;
    206 	rap->width = dc->dc_wid;
    207 	rap->height = dc->dc_ht;
    208 	rap->depth = color ? 16 : 2;
    209 	rap->linelongs = dc->dc_rowbytes / sizeof(u_int32_t);
    210 	rap->pixels = (u_int32_t *)dc->dc_videobase;
    211 
    212 	/* initialize the raster console blitter */
    213 	rcp = &dc->dc_rcons;
    214 	rcp->rc_sp = rap;
    215 	rcp->rc_crow = rcp->rc_ccol = -1;
    216 	rcp->rc_crowp = &rcp->rc_crow;
    217 	rcp->rc_ccolp = &rcp->rc_ccol;
    218 	rcons_init(rcp, 34, 80);
    219 
    220 	if (color) {
    221 		nextdisplay_color.nrows = dc->dc_rcons.rc_maxrow;
    222 		nextdisplay_color.ncols = dc->dc_rcons.rc_maxcol;
    223 	} else {
    224 		nextdisplay_mono.nrows = dc->dc_rcons.rc_maxrow;
    225 		nextdisplay_mono.ncols = dc->dc_rcons.rc_maxcol;
    226 	}
    227 }
    228 
    229 void
    230 nextdisplay_attach(parent, self, aux)
    231 	struct device *parent;
    232 	struct device *self;
    233 	void *aux;
    234 {
    235 	struct nextdisplay_softc *sc;
    236 	struct wsemuldisplaydev_attach_args waa;
    237 	int isconsole;
    238 	int iscolor;
    239 	paddr_t addr;
    240 
    241 	sc = (struct nextdisplay_softc *)self;
    242 
    243 	if ((rom_machine_type == NeXT_WARP9C)
    244 	    || (rom_machine_type == NeXT_TURBO_COLOR)) {
    245 		iscolor = 1;
    246 		addr = (paddr_t)colorbase;
    247 	} else {
    248 		iscolor = 0;
    249 		addr = (paddr_t)monobase;
    250 	}
    251 
    252 	isconsole = nextdisplay_is_console(addr);
    253 
    254 	if (isconsole) {
    255 		sc->sc_dc = &nextdisplay_console_dc;
    256 		sc->nscreens = 1;
    257 	} else {
    258 		sc->sc_dc = (struct nextdisplay_config *)
    259 				malloc(sizeof(struct nextdisplay_config), M_DEVBUF, M_WAITOK);
    260 		nextdisplay_init(sc->sc_dc, iscolor);
    261 	}
    262 
    263 	printf(": %d x %d, %dbpp\n", sc->sc_dc->dc_wid, sc->sc_dc->dc_ht,
    264 	       sc->sc_dc->dc_depth);
    265 
    266 	/* initialize the raster */
    267 	waa.console = isconsole;
    268 	waa.scrdata = iscolor ? &nextdisplay_screenlist_color : &nextdisplay_screenlist_mono;
    269 	waa.accessops = &nextdisplay_accessops;
    270 	waa.accesscookie = sc;
    271 #if 0
    272 	printf("nextdisplay: access cookie is %p\n", sc);
    273 #endif
    274 	config_found(self, &waa, wsemuldisplaydevprint);
    275 }
    276 
    277 
    278 int
    279 nextdisplay_ioctl(v, cmd, data, flag, p)
    280 	void *v;
    281 	u_long cmd;
    282 	caddr_t data;
    283 	int flag;
    284 	struct proc *p;
    285 {
    286 	struct nextdisplay_softc *sc = v;
    287 	struct nextdisplay_config *dc = sc->sc_dc;
    288 
    289 	switch (cmd) {
    290 	case WSDISPLAYIO_GTYPE:
    291 		*(int *)data = dc->dc_type;
    292 		return 0;
    293 
    294 	case WSDISPLAYIO_SCURSOR:
    295 		printf("nextdisplay_ioctl: wsdisplayio_scursor\n");
    296 		return EPASSTHROUGH;
    297 
    298 	case WSDISPLAYIO_SCURPOS:
    299 		printf("nextdisplay_ioctl: wsdisplayio_scurpos\n");
    300 		return EPASSTHROUGH;
    301 
    302 	case WSDISPLAYIO_GINFO:
    303 	case WSDISPLAYIO_GETCMAP:
    304 	case WSDISPLAYIO_PUTCMAP:
    305 	case WSDISPLAYIO_GVIDEO:
    306 	case WSDISPLAYIO_SVIDEO:
    307 	case WSDISPLAYIO_GCURPOS:
    308 	case WSDISPLAYIO_GCURMAX:
    309 	case WSDISPLAYIO_GCURSOR:
    310 		printf("nextdisplay_ioctl: listed but unsupported ioctl\n");
    311 		return EPASSTHROUGH;
    312 	}
    313 
    314 	return EPASSTHROUGH;
    315 }
    316 
    317 static paddr_t
    318 nextdisplay_mmap(v, offset, prot)
    319 	void *v;
    320 	off_t offset;
    321 	int prot;
    322 {
    323 
    324 	/* XXX */
    325 	printf("nextdisplay_mmap: failed\n");
    326 	return -1;
    327 }
    328 
    329 int
    330 nextdisplay_alloc_screen(v, type, cookiep, curxp, curyp, defattrp)
    331 	void *v;
    332 	const struct wsscreen_descr *type;
    333 	void **cookiep;
    334 	int *curxp, *curyp;
    335 	long *defattrp;
    336 {
    337 	struct nextdisplay_softc *sc = v;
    338 	long defattr;
    339 
    340 	/* only allow one screen */
    341 	if (sc->nscreens > 0)
    342 		return (ENOMEM);
    343 
    344 	*cookiep = &sc->sc_dc->dc_rcons; /* one and only for now */
    345 	*curxp = 0;
    346 	*curyp = 0;
    347 	rcons_allocattr(&sc->sc_dc->dc_rcons, 0, 0,
    348 			(strcmp(type->name, "color") == 0)
    349 			? 0
    350 			: WSATTR_REVERSE, &defattr);
    351 	*defattrp = defattr;
    352 	sc->nscreens++;
    353 #if 0
    354 	printf("nextdisplay: allocating screen\n");
    355 #endif
    356 	return (0);
    357 }
    358 
    359 void
    360 nextdisplay_free_screen(v, cookie)
    361 	void *v;
    362 	void *cookie;
    363 {
    364 	struct nextdisplay_softc *sc = v;
    365 
    366 	if (sc->sc_dc == &nextdisplay_console_dc)
    367 		panic("nextdisplay_free_screen: console");
    368 
    369 	sc->nscreens--;
    370 }
    371 
    372 int
    373 nextdisplay_show_screen(v, cookie, waitok, cb, cbarg)
    374 	void *v;
    375 	void *cookie;
    376 	int waitok;
    377 	void (*cb) __P((void *, int, int));
    378 	void *cbarg;
    379 {
    380 
    381 	return (0);
    382 }
    383 
    384 static int
    385 nextdisplay_load_font(v, cookie, font)
    386 	void *v;
    387 	void *cookie;
    388 	struct wsdisplay_font *font;
    389 {
    390 	return (EPASSTHROUGH);
    391 }
    392 
    393 int
    394 nextdisplay_cnattach(void)
    395 {
    396 	struct nextdisplay_config *dc = &nextdisplay_console_dc;
    397 	long defattr;
    398 	int iscolor;
    399 
    400 	if ((rom_machine_type == NeXT_WARP9C)
    401 	    || (rom_machine_type == NeXT_TURBO_COLOR)) {
    402 		iscolor = 1;
    403 		nextdisplay_consaddr = (paddr_t)colorbase;
    404 	} else {
    405 		iscolor = 0;
    406 		nextdisplay_consaddr = (paddr_t)monobase;
    407 	}
    408 
    409 	/* set up the display */
    410 	nextdisplay_init(&nextdisplay_console_dc, iscolor);
    411 
    412 	rcons_allocattr(&dc->dc_rcons, 0, 0,
    413 			iscolor ? 0 : WSATTR_REVERSE, &defattr);
    414 
    415 	wsdisplay_cnattach(iscolor ? &nextdisplay_color : &nextdisplay_mono,
    416 			   &dc->dc_rcons, 0, 0, defattr);
    417 
    418 	dc->isconsole = 1;
    419 	return (0);
    420 }
    421