bwtwo.c revision 1.24
15084Sjohnlev/*	$NetBSD: bwtwo.c,v 1.24 2009/03/14 21:04:23 dsl Exp $ */
25084Sjohnlev
35084Sjohnlev/*-
45084Sjohnlev * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
55084Sjohnlev * All rights reserved.
65084Sjohnlev *
75084Sjohnlev * This code is derived from software contributed to The NetBSD Foundation
85084Sjohnlev * by Jason R. Thorpe.
95084Sjohnlev *
105084Sjohnlev * Redistribution and use in source and binary forms, with or without
115084Sjohnlev * modification, are permitted provided that the following conditions
125084Sjohnlev * are met:
135084Sjohnlev * 1. Redistributions of source code must retain the above copyright
145084Sjohnlev *    notice, this list of conditions and the following disclaimer.
155084Sjohnlev * 2. Redistributions in binary form must reproduce the above copyright
165084Sjohnlev *    notice, this list of conditions and the following disclaimer in the
175084Sjohnlev *    documentation and/or other materials provided with the distribution.
185084Sjohnlev *
195084Sjohnlev * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
205084Sjohnlev * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
215084Sjohnlev * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
225084Sjohnlev * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
235084Sjohnlev * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
245084Sjohnlev * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
255084Sjohnlev * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
265084Sjohnlev * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
275084Sjohnlev * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
285084Sjohnlev * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
295084Sjohnlev * POSSIBILITY OF SUCH DAMAGE.
305084Sjohnlev */
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.24 2009/03/14 21:04:23 dsl 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/malloc.h>
89#include <sys/mman.h>
90#include <sys/tty.h>
91#include <sys/conf.h>
92
93#include <machine/autoconf.h>
94#include <machine/eeprom.h>
95
96#include <dev/sun/fbio.h>
97#include <dev/sun/fbvar.h>
98
99#include <dev/sun/btreg.h>
100#include <dev/sun/bwtworeg.h>
101#include <dev/sun/bwtwovar.h>
102#include <dev/sun/pfourreg.h>
103
104#if NWSDISPLAY > 0
105#include <dev/wscons/wsconsio.h>
106#include <dev/wsfont/wsfont.h>
107#include <dev/rasops/rasops.h>
108
109#include "opt_wsemul.h"
110#endif
111
112extern struct cfdriver bwtwo_cd;
113
114dev_type_open(bwtwoopen);
115dev_type_ioctl(bwtwoioctl);
116dev_type_mmap(bwtwommap);
117
118const struct cdevsw bwtwo_cdevsw = {
119	bwtwoopen, nullclose, noread, nowrite, bwtwoioctl,
120	nostop, notty, nopoll, bwtwommap, nokqfilter,
121};
122
123/* XXX we do not handle frame buffer interrupts (do not know how) */
124static void	bwtwounblank(struct device *);
125
126/* frame buffer generic driver */
127static struct fbdriver bwtwofbdriver = {
128	bwtwounblank, bwtwoopen, nullclose, bwtwoioctl, nopoll, bwtwommap,
129	nokqfilter
130};
131
132#if NWSDISPLAY > 0
133#ifdef RASTERCONSOLE
134#error RASTERCONSOLE and wsdisplay are mutually exclusive
135#endif
136
137struct wsscreen_descr bwtwo_defaultscreen = {
138	"std",
139	0, 0,	/* will be filled in -- XXX shouldn't, it's global */
140	NULL,		/* textops */
141	8, 16,	/* font width/height */
142	0,	/* capabilities */
143	NULL	/* modecookie */
144};
145
146static int 	bwtwo_ioctl(void *, void *, u_long, void *, int, struct lwp *);
147static paddr_t	bwtwo_mmap(void *, void *, off_t, int);
148static void	bwtwo_init_screen(void *, struct vcons_screen *, int, long *);
149
150struct wsdisplay_accessops bwtwo_accessops = {
151	bwtwo_ioctl,
152	bwtwo_mmap,
153	NULL,	/* alloc_screen */
154	NULL,	/* free_screen */
155	NULL,	/* show_screen */
156	NULL, 	/* load_font */
157	NULL,	/* pollc */
158	NULL	/* scroll */
159};
160
161const struct wsscreen_descr *_bwtwo_scrlist[] = {
162	&bwtwo_defaultscreen
163};
164
165struct wsscreen_list bwtwo_screenlist = {
166	sizeof(_bwtwo_scrlist) / sizeof(struct wsscreen_descr *),
167	_bwtwo_scrlist
168};
169
170
171static struct vcons_screen bw2_console_screen;
172#endif /* NWSDISPLAY > 0 */
173
174int
175bwtwo_pfour_probe(void *vaddr, void *arg)
176{
177	struct cfdata *cf = arg;
178
179	switch (fb_pfour_id(vaddr)) {
180	case PFOUR_ID_BW:
181	case PFOUR_ID_COLOR8P1:		/* bwtwo in ... */
182	case PFOUR_ID_COLOR24:		/* ...overlay plane */
183		/* This is wrong; should be done in bwtwo_attach() */
184		cf->cf_flags |= FB_PFOUR;
185		/* FALLTHROUGH */
186	case PFOUR_NOTPFOUR:
187		return (1);
188	}
189	return (0);
190}
191
192void
193bwtwoattach(struct bwtwo_softc *sc, const char *name, int isconsole)
194{
195	struct fbdevice *fb = &sc->sc_fb;
196	int isoverlay;
197#if NWSDISPLAY > 0
198	struct wsemuldisplaydev_attach_args aa;
199	struct rasops_info *ri = &bw2_console_screen.scr_ri;
200	unsigned long defattr;
201#endif
202
203	/* Fill in the remaining fbdevice values */
204	fb->fb_driver = &bwtwofbdriver;
205	fb->fb_device = &sc->sc_dev;
206	fb->fb_type.fb_type = FBTYPE_SUN2BW;
207	fb->fb_type.fb_cmsize = 0;
208	fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes;
209	printf(": %s, %d x %d", name,
210	       fb->fb_type.fb_width, fb->fb_type.fb_height);
211
212	/* Are we an overlay bw2? */
213	if ((fb->fb_flags & FB_PFOUR) == 0 || (sc->sc_ovtype == BWO_NONE))
214		isoverlay = 0;
215	else
216		isoverlay = 1;
217
218	/* Insure video is enabled */
219	sc->sc_set_video(sc, 1);
220
221	if (isconsole) {
222		printf(" (console)\n");
223#ifdef RASTERCONSOLE
224		/*
225		 * XXX rcons doesn't seem to work properly on the overlay
226		 * XXX plane.  This is a temporary kludge until someone
227		 * XXX fixes it.
228		 */
229		if (!isoverlay)
230			fbrcons_init(fb);
231#endif
232	} else
233		printf("\n");
234
235	if (isoverlay) {
236		const char *ovnam;
237
238		switch (sc->sc_ovtype) {
239		case BWO_CGFOUR:
240			ovnam = "cgfour";
241			break;
242
243		case BWO_CGEIGHT:
244			ovnam = "cgeight";
245			break;
246
247		default:
248			ovnam = "unknown";
249			break;
250		}
251		printf("%s: %s overlay plane\n", device_xname(&sc->sc_dev), ovnam);
252	}
253
254	/*
255	 * If we're on an overlay plane of a color framebuffer,
256	 * then we don't force the issue in fb_attach() because
257	 * we'd like the color framebuffer to actually be the
258	 * "console framebuffer".  We're only around to speed
259	 * up rconsole.
260	 */
261	if (isoverlay)
262		fb_attach(fb, 0);
263	else
264		fb_attach(fb, isconsole);
265
266#if NWSDISPLAY > 0
267	sc->sc_width = fb->fb_type.fb_width;
268	sc->sc_stride = fb->fb_type.fb_width/8;
269	sc->sc_height = fb->fb_type.fb_height;
270
271	/* setup rasops and so on for wsdisplay */
272	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
273
274	vcons_init(&sc->vd, sc, &bwtwo_defaultscreen, &bwtwo_accessops);
275	sc->vd.init_screen = bwtwo_init_screen;
276
277	if(isconsole && !isoverlay) {
278		/* we mess with bw2_console_screen only once */
279		vcons_init_screen(&sc->vd, &bw2_console_screen, 1,
280		    &defattr);
281		bw2_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
282
283		bwtwo_defaultscreen.textops = &ri->ri_ops;
284		bwtwo_defaultscreen.capabilities = ri->ri_caps;
285		bwtwo_defaultscreen.nrows = ri->ri_rows;
286		bwtwo_defaultscreen.ncols = ri->ri_cols;
287		sc->vd.active = &bw2_console_screen;
288		wsdisplay_cnattach(&bwtwo_defaultscreen, ri, 0, 0, defattr);
289	} else {
290		/*
291		 * we're not the console so we just clear the screen and don't
292		 * set up any sort of text display
293		 */
294		if (bwtwo_defaultscreen.textops == NULL) {
295			/*
296			 * ugly, but...
297			 * we want the console settings to win, so we only
298			 * touch anything when we find an untouched screen
299			 * definition. In this case we fill it from fb to
300			 * avoid problems in case no bwtwo is the console
301			 */
302			ri = &sc->sc_fb.fb_rinfo;
303			bwtwo_defaultscreen.textops = &ri->ri_ops;
304			bwtwo_defaultscreen.capabilities = ri->ri_caps;
305			bwtwo_defaultscreen.nrows = ri->ri_rows;
306			bwtwo_defaultscreen.ncols = ri->ri_cols;
307		}
308	}
309
310	aa.scrdata = &bwtwo_screenlist;
311	if (isoverlay)
312		aa.console = 0;
313	else
314		aa.console = isconsole;
315	aa.accessops = &bwtwo_accessops;
316	aa.accesscookie = &sc->vd;
317	config_found(&sc->sc_dev, &aa, wsemuldisplaydevprint);
318#endif
319
320}
321
322int
323bwtwoopen(dev_t dev, int flags, int mode, struct lwp *l)
324{
325	int unit = minor(dev);
326
327	if (device_lookup(&bwtwo_cd, unit) == NULL)
328		return (ENXIO);
329
330	return (0);
331}
332
333int
334bwtwoioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l)
335{
336	struct bwtwo_softc *sc = device_lookup_private(&bwtwo_cd, minor(dev));
337
338	switch (cmd) {
339
340	case FBIOGTYPE:
341		*(struct fbtype *)data = sc->sc_fb.fb_type;
342		break;
343
344	case FBIOGVIDEO:
345		*(int *)data = sc->sc_get_video(sc);
346		break;
347
348	case FBIOSVIDEO:
349		sc->sc_set_video(sc, (*(int *)data));
350		break;
351
352	default:
353		return (ENOTTY);
354	}
355	return (0);
356}
357
358static void
359bwtwounblank(struct device *dev)
360{
361	struct bwtwo_softc *sc = device_private(dev);
362
363	sc->sc_set_video(sc, 1);
364}
365
366/*
367 * Return the address that would map the given device at the given
368 * offset, allowing for the given protection, or return -1 for error.
369 */
370paddr_t
371bwtwommap(dev_t dev, off_t off, int prot)
372{
373	struct bwtwo_softc *sc = device_lookup_private(&bwtwo_cd, minor(dev));
374
375	if (off & PGOFSET)
376		panic("bwtwommap");
377
378	if (off >= sc->sc_fb.fb_type.fb_size)
379		return (-1);
380
381	return (bus_space_mmap(sc->sc_bustag,
382		sc->sc_paddr, sc->sc_pixeloffset + off,
383		prot, BUS_SPACE_MAP_LINEAR));
384}
385
386#if NWSDISPLAY > 0
387
388int
389bwtwo_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
390	struct lwp *l)
391{
392	/* we'll probably need to add more stuff here */
393	struct vcons_data *vd = v;
394	struct bwtwo_softc *sc = vd->cookie;
395	struct wsdisplay_fbinfo *wdf;
396	struct rasops_info *ri = &sc->sc_fb.fb_rinfo;
397	struct vcons_screen *ms = sc->vd.active;
398	switch (cmd) {
399		case WSDISPLAYIO_GTYPE:
400			*(u_int *)data = WSDISPLAY_TYPE_GENFB;
401			return 0;
402		case WSDISPLAYIO_GINFO:
403			wdf = (void *)data;
404			wdf->height = ri->ri_height;
405			wdf->width = ri->ri_width;
406			wdf->depth = ri->ri_depth;
407			wdf->cmsize = 0;
408			return 0;
409
410		case WSDISPLAYIO_GETCMAP:
411			return EINVAL;
412		case WSDISPLAYIO_PUTCMAP:
413			return EINVAL;
414
415		case WSDISPLAYIO_SMODE:
416			{
417				int new_mode = *(int*)data;
418				if (new_mode != sc->sc_mode)
419				{
420					sc->sc_mode = new_mode;
421					if(new_mode == WSDISPLAYIO_MODE_EMUL)
422					{
423						vcons_redraw_screen(ms);
424					}
425				}
426			}
427	}
428	return EPASSTHROUGH;
429}
430
431paddr_t
432bwtwo_mmap(void *v, void *vs, off_t offset, int prot)
433{
434	/* I'm not at all sure this is the right thing to do */
435	return bwtwommap(0, offset, prot); /* assume minor dev 0 for now */
436}
437
438void
439bwtwo_init_screen(void *cookie, struct vcons_screen *scr,
440    int existing, long *defattr)
441{
442	struct bwtwo_softc *sc = cookie;
443	struct rasops_info *ri = &scr->scr_ri;
444
445	ri->ri_depth = 1;
446	ri->ri_width = sc->sc_width;
447	ri->ri_height = sc->sc_height;
448	ri->ri_stride = sc->sc_stride;
449	ri->ri_flg = RI_CENTER;
450
451	ri->ri_bits = sc->sc_fb.fb_pixels;
452
453	memset(sc->sc_fb.fb_pixels, (*defattr >> 16) & 0xff,
454	    sc->sc_stride * sc->sc_height);
455	rasops_init(ri, sc->sc_height/8, sc->sc_width/8);
456	ri->ri_caps = 0;
457	rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
458		    sc->sc_width / ri->ri_font->fontwidth);
459
460	ri->ri_hw = scr;
461}
462
463#endif /* NWSDISPLAY > 0 */
464