xref: /csrg-svn/sys/sparc/sbus/bwtwo.c (revision 63322)
155135Storek /*
2*63322Sbostic  * Copyright (c) 1992, 1993
3*63322Sbostic  *	The Regents of the University of California.  All rights reserved.
455135Storek  *
555135Storek  * This software was developed by the Computer Systems Engineering group
655135Storek  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
755135Storek  * contributed to Berkeley.
855135Storek  *
955503Sbostic  * All advertising materials mentioning features or use of this software
1055503Sbostic  * must display the following acknowledgement:
1155503Sbostic  *	This product includes software developed by the University of
1259213Storek  *	California, Lawrence Berkeley Laboratory.
1355503Sbostic  *
1455135Storek  * %sccs.include.redist.c%
1555135Storek  *
16*63322Sbostic  *	@(#)bwtwo.c	8.1 (Berkeley) 06/11/93
1755135Storek  *
1859213Storek  * from: $Header: bwtwo.c,v 1.14 92/11/26 02:28:04 torek Exp $
1955135Storek  */
2055135Storek 
2155135Storek /*
2255135Storek  * black&white display (bwtwo) driver.
2355135Storek  *
2455135Storek  * Does not handle interrupts, even though they can occur.
2555135Storek  */
2655135Storek 
2756540Sbostic #include <sys/param.h>
2856540Sbostic #include <sys/device.h>
2956540Sbostic #include <sys/fbio.h>
3056540Sbostic #include <sys/ioctl.h>
3156540Sbostic #include <sys/malloc.h>
3256540Sbostic #include <sys/mman.h>
3356540Sbostic #include <sys/tty.h>
3455135Storek 
3556540Sbostic #include <machine/autoconf.h>
3656540Sbostic #include <machine/pmap.h>
3756540Sbostic #include <machine/fbvar.h>
3855135Storek 
3956540Sbostic #include <sparc/sbus/bwtworeg.h>
4056540Sbostic #include <sparc/sbus/sbusvar.h>
4155135Storek 
4255135Storek /* per-display variables */
4355135Storek struct bwtwo_softc {
4455135Storek 	struct	device sc_dev;		/* base device */
4555135Storek 	struct	sbusdev sc_sd;		/* sbus device */
4655135Storek 	struct	fbdevice sc_fb;		/* frame buffer device */
4755135Storek 	volatile struct bwtworeg *sc_reg;/* control registers */
4855135Storek 	caddr_t	sc_phys;		/* display RAM (phys addr) */
4955135Storek };
5055135Storek 
5155135Storek /* autoconfiguration driver */
5255135Storek static void	bwtwoattach(struct device *, struct device *, void *);
5355135Storek struct cfdriver bwtwocd =
5455135Storek     { NULL, "bwtwo", matchbyname, bwtwoattach,
5555135Storek       DV_DULL, sizeof(struct bwtwo_softc) };
5655135Storek 
5755135Storek /* XXX we do not handle frame buffer interrupts (do not know how) */
5855135Storek 
5955135Storek /* frame buffer generic driver */
6055135Storek static void	bwtwounblank(struct device *);
6155135Storek static struct fbdriver bwtwofbdriver = { bwtwounblank };
6255135Storek 
6355135Storek extern int fbnode;
6455135Storek extern struct tty *fbconstty;
6555135Storek extern int (*v_putc)();
6655135Storek extern int nullop();
6755135Storek static int bwtwo_cnputc();
6855135Storek static struct bwtwo_softc *bwcons;
6955135Storek 
7055135Storek #define	BWTWO_MAJOR	27		/* XXX */
7155135Storek 
7255135Storek /*
7355135Storek  * Attach a display.  We need to notice if it is the console, too.
7455135Storek  */
7555135Storek void
bwtwoattach(parent,self,args)7655135Storek bwtwoattach(parent, self, args)
7755135Storek 	struct device *parent, *self;
7855135Storek 	void *args;
7955135Storek {
8055135Storek 	register struct bwtwo_softc *sc = (struct bwtwo_softc *)self;
8155135Storek 	register struct sbus_attach_args *sa = args;
8255135Storek 	register int node = sa->sa_ra.ra_node, ramsize;
8355135Storek 	register struct bwtwo_all *p;
8455135Storek 	int isconsole;
8555135Storek 
8655135Storek 	sc->sc_fb.fb_major = BWTWO_MAJOR;	/* XXX to be removed */
8755135Storek 
8855135Storek 	sc->sc_fb.fb_driver = &bwtwofbdriver;
8955135Storek 	sc->sc_fb.fb_device = &sc->sc_dev;
9055135Storek 	/*
9155135Storek 	 * The defaults below match my screen, but are not guaranteed
9255135Storek 	 * to be correct as defaults go...
9355135Storek 	 */
9455135Storek 	sc->sc_fb.fb_type.fb_type = FBTYPE_SUN2BW;
9555135Storek 	sc->sc_fb.fb_type.fb_width = getpropint(node, "width", 1152);
9655135Storek 	sc->sc_fb.fb_type.fb_height = getpropint(node, "height", 900);
9755135Storek 	sc->sc_fb.fb_linebytes = getpropint(node, "linebytes", 144);
9855135Storek 	ramsize = sc->sc_fb.fb_type.fb_height * sc->sc_fb.fb_linebytes;
9955135Storek 	sc->sc_fb.fb_type.fb_depth = 1;
10055135Storek 	sc->sc_fb.fb_type.fb_cmsize = 0;
10155135Storek 	sc->sc_fb.fb_type.fb_size = ramsize;
10255135Storek 	printf(": %s, %d x %d", getpropstring(node, "model"),
10355135Storek 	    sc->sc_fb.fb_type.fb_width, sc->sc_fb.fb_type.fb_height);
10455135Storek 
10555135Storek 	/*
10655135Storek 	 * When the ROM has mapped in a bwtwo display, the address
10755135Storek 	 * maps only the video RAM, so in any case we have to map the
10855135Storek 	 * registers ourselves.  We only need the video RAM if we are
10955135Storek 	 * going to print characters via rconsole.
11055135Storek 	 */
11155135Storek 	isconsole = node == fbnode && fbconstty != NULL;
11255135Storek 	p = (struct bwtwo_all *)sa->sa_ra.ra_paddr;
11355135Storek 	if ((sc->sc_fb.fb_pixels = sa->sa_ra.ra_vaddr) == NULL && isconsole) {
11455135Storek 		/* this probably cannot happen, but what the heck */
11555135Storek 		sc->sc_fb.fb_pixels = mapiodev(p->ba_ram, ramsize);
11655135Storek 	}
11755135Storek 	sc->sc_reg = (volatile struct bwtworeg *)
11855135Storek 	    mapiodev((caddr_t)&p->ba_reg, sizeof(p->ba_reg));
11955135Storek 	sc->sc_phys = p->ba_ram;
12055135Storek 
12155135Storek 	/* Insure video is enabled */
12255135Storek 	sc->sc_reg->bw_ctl |= CTL_VE;
12355135Storek 
12455135Storek 	if (isconsole) {
12555135Storek 		printf(" (console)\n");
12655135Storek #ifdef RCONSOLE
12755135Storek 		rcons_init(&sc->sc_fb);
12855135Storek #endif
12955135Storek 	} else
13055135Storek 		printf("\n");
13155135Storek 	sbus_establish(&sc->sc_sd, &sc->sc_dev);
13255135Storek 	if (node == fbnode)
13355135Storek 		fb_attach(&sc->sc_fb);
13455135Storek }
13555135Storek 
13655135Storek int
bwtwoopen(dev,flags,mode,p)13755135Storek bwtwoopen(dev, flags, mode, p)
13855135Storek 	dev_t dev;
13955135Storek 	int flags, mode;
14055135Storek 	struct proc *p;
14155135Storek {
14255135Storek 	int unit = minor(dev);
14355135Storek 
14455135Storek 	if (unit >= bwtwocd.cd_ndevs || bwtwocd.cd_devs[unit] == NULL)
14555135Storek 		return (ENXIO);
14655135Storek 	return (0);
14755135Storek }
14855135Storek 
14955135Storek int
bwtwoclose(dev,flags,mode,p)15055135Storek bwtwoclose(dev, flags, mode, p)
15155135Storek 	dev_t dev;
15255135Storek 	int flags, mode;
15355135Storek 	struct proc *p;
15455135Storek {
15555135Storek 
15655135Storek 	return (0);
15755135Storek }
15855135Storek 
15955135Storek int
bwtwoioctl(dev,cmd,data,flags,p)16055135Storek bwtwoioctl(dev, cmd, data, flags, p)
16155135Storek 	dev_t dev;
16255135Storek 	int cmd;
16355135Storek 	caddr_t data;
16455135Storek 	int flags;
16555135Storek 	struct proc *p;
16655135Storek {
16755135Storek 	struct bwtwo_softc *sc = bwtwocd.cd_devs[minor(dev)];
16855135Storek 
16955135Storek 	switch (cmd) {
17055135Storek 
17155135Storek 	case FBIOGTYPE:
17255135Storek 		*(struct fbtype *)data = sc->sc_fb.fb_type;
17355135Storek 		break;
17455135Storek 
17555135Storek 	case FBIOGVIDEO:
17655135Storek 		*(int *)data = (sc->sc_reg->bw_ctl & CTL_VE) != 0;
17755135Storek 		break;
17855135Storek 
17955135Storek 	case FBIOSVIDEO:
18055135Storek 		if (*(int *)data)
18155135Storek 			sc->sc_reg->bw_ctl |= CTL_VE;
18255135Storek 		else
18355135Storek 			sc->sc_reg->bw_ctl &= ~CTL_VE;
18455135Storek 		break;
18555135Storek 
18655135Storek 	default:
18755135Storek 		return (ENOTTY);
18855135Storek 	}
18955135Storek 	return (0);
19055135Storek }
19155135Storek 
19255135Storek static void
bwtwounblank(dev)19355135Storek bwtwounblank(dev)
19455135Storek 	struct device *dev;
19555135Storek {
19655135Storek 	struct bwtwo_softc *sc = (struct bwtwo_softc *)dev;
19755135Storek 
19855135Storek 	sc->sc_reg->bw_ctl |= CTL_VE;
19955135Storek }
20055135Storek 
20155135Storek /*
20255135Storek  * Return the address that would map the given device at the given
20355135Storek  * offset, allowing for the given protection, or return -1 for error.
20455135Storek  */
20555135Storek int
bwtwomap(dev,off,prot)20655135Storek bwtwomap(dev, off, prot)
20755135Storek 	dev_t dev;
20855135Storek 	int off, prot;
20955135Storek {
21055135Storek 	register struct bwtwo_softc *sc = bwtwocd.cd_devs[minor(dev)];
21155135Storek 
21255135Storek 	if (off & PGOFSET)
21355135Storek 		panic("bwtwomap");
21455135Storek 	if ((unsigned)off >= sc->sc_fb.fb_type.fb_size)
21555135Storek 		return (-1);
21655135Storek 	/*
21755135Storek 	 * I turned on PMAP_NC here to disable the cache as I was
21855135Storek 	 * getting horribly broken behaviour with it on.
21955135Storek 	 */
22055135Storek 	return ((int)sc->sc_phys + off + PMAP_OBIO + PMAP_NC);
22155135Storek }
222