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