1 /*
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This software was developed by the Computer Systems Engineering group
6 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7 * contributed to Berkeley.
8 *
9 * All advertising materials mentioning features or use of this software
10 * must display the following acknowledgement:
11 * This product includes software developed by the University of
12 * California, Lawrence Berkeley Laboratory.
13 *
14 * %sccs.include.redist.c%
15 *
16 * @(#)bwtwo.c 8.1 (Berkeley) 06/11/93
17 *
18 * from: $Header: bwtwo.c,v 1.14 92/11/26 02:28:04 torek Exp $
19 */
20
21 /*
22 * black&white display (bwtwo) driver.
23 *
24 * Does not handle interrupts, even though they can occur.
25 */
26
27 #include <sys/param.h>
28 #include <sys/device.h>
29 #include <sys/fbio.h>
30 #include <sys/ioctl.h>
31 #include <sys/malloc.h>
32 #include <sys/mman.h>
33 #include <sys/tty.h>
34
35 #include <machine/autoconf.h>
36 #include <machine/pmap.h>
37 #include <machine/fbvar.h>
38
39 #include <sparc/sbus/bwtworeg.h>
40 #include <sparc/sbus/sbusvar.h>
41
42 /* per-display variables */
43 struct bwtwo_softc {
44 struct device sc_dev; /* base device */
45 struct sbusdev sc_sd; /* sbus device */
46 struct fbdevice sc_fb; /* frame buffer device */
47 volatile struct bwtworeg *sc_reg;/* control registers */
48 caddr_t sc_phys; /* display RAM (phys addr) */
49 };
50
51 /* autoconfiguration driver */
52 static void bwtwoattach(struct device *, struct device *, void *);
53 struct cfdriver bwtwocd =
54 { NULL, "bwtwo", matchbyname, bwtwoattach,
55 DV_DULL, sizeof(struct bwtwo_softc) };
56
57 /* XXX we do not handle frame buffer interrupts (do not know how) */
58
59 /* frame buffer generic driver */
60 static void bwtwounblank(struct device *);
61 static struct fbdriver bwtwofbdriver = { bwtwounblank };
62
63 extern int fbnode;
64 extern struct tty *fbconstty;
65 extern int (*v_putc)();
66 extern int nullop();
67 static int bwtwo_cnputc();
68 static struct bwtwo_softc *bwcons;
69
70 #define BWTWO_MAJOR 27 /* XXX */
71
72 /*
73 * Attach a display. We need to notice if it is the console, too.
74 */
75 void
bwtwoattach(parent,self,args)76 bwtwoattach(parent, self, args)
77 struct device *parent, *self;
78 void *args;
79 {
80 register struct bwtwo_softc *sc = (struct bwtwo_softc *)self;
81 register struct sbus_attach_args *sa = args;
82 register int node = sa->sa_ra.ra_node, ramsize;
83 register struct bwtwo_all *p;
84 int isconsole;
85
86 sc->sc_fb.fb_major = BWTWO_MAJOR; /* XXX to be removed */
87
88 sc->sc_fb.fb_driver = &bwtwofbdriver;
89 sc->sc_fb.fb_device = &sc->sc_dev;
90 /*
91 * The defaults below match my screen, but are not guaranteed
92 * to be correct as defaults go...
93 */
94 sc->sc_fb.fb_type.fb_type = FBTYPE_SUN2BW;
95 sc->sc_fb.fb_type.fb_width = getpropint(node, "width", 1152);
96 sc->sc_fb.fb_type.fb_height = getpropint(node, "height", 900);
97 sc->sc_fb.fb_linebytes = getpropint(node, "linebytes", 144);
98 ramsize = sc->sc_fb.fb_type.fb_height * sc->sc_fb.fb_linebytes;
99 sc->sc_fb.fb_type.fb_depth = 1;
100 sc->sc_fb.fb_type.fb_cmsize = 0;
101 sc->sc_fb.fb_type.fb_size = ramsize;
102 printf(": %s, %d x %d", getpropstring(node, "model"),
103 sc->sc_fb.fb_type.fb_width, sc->sc_fb.fb_type.fb_height);
104
105 /*
106 * When the ROM has mapped in a bwtwo display, the address
107 * maps only the video RAM, so in any case we have to map the
108 * registers ourselves. We only need the video RAM if we are
109 * going to print characters via rconsole.
110 */
111 isconsole = node == fbnode && fbconstty != NULL;
112 p = (struct bwtwo_all *)sa->sa_ra.ra_paddr;
113 if ((sc->sc_fb.fb_pixels = sa->sa_ra.ra_vaddr) == NULL && isconsole) {
114 /* this probably cannot happen, but what the heck */
115 sc->sc_fb.fb_pixels = mapiodev(p->ba_ram, ramsize);
116 }
117 sc->sc_reg = (volatile struct bwtworeg *)
118 mapiodev((caddr_t)&p->ba_reg, sizeof(p->ba_reg));
119 sc->sc_phys = p->ba_ram;
120
121 /* Insure video is enabled */
122 sc->sc_reg->bw_ctl |= CTL_VE;
123
124 if (isconsole) {
125 printf(" (console)\n");
126 #ifdef RCONSOLE
127 rcons_init(&sc->sc_fb);
128 #endif
129 } else
130 printf("\n");
131 sbus_establish(&sc->sc_sd, &sc->sc_dev);
132 if (node == fbnode)
133 fb_attach(&sc->sc_fb);
134 }
135
136 int
bwtwoopen(dev,flags,mode,p)137 bwtwoopen(dev, flags, mode, p)
138 dev_t dev;
139 int flags, mode;
140 struct proc *p;
141 {
142 int unit = minor(dev);
143
144 if (unit >= bwtwocd.cd_ndevs || bwtwocd.cd_devs[unit] == NULL)
145 return (ENXIO);
146 return (0);
147 }
148
149 int
bwtwoclose(dev,flags,mode,p)150 bwtwoclose(dev, flags, mode, p)
151 dev_t dev;
152 int flags, mode;
153 struct proc *p;
154 {
155
156 return (0);
157 }
158
159 int
bwtwoioctl(dev,cmd,data,flags,p)160 bwtwoioctl(dev, cmd, data, flags, p)
161 dev_t dev;
162 int cmd;
163 caddr_t data;
164 int flags;
165 struct proc *p;
166 {
167 struct bwtwo_softc *sc = bwtwocd.cd_devs[minor(dev)];
168
169 switch (cmd) {
170
171 case FBIOGTYPE:
172 *(struct fbtype *)data = sc->sc_fb.fb_type;
173 break;
174
175 case FBIOGVIDEO:
176 *(int *)data = (sc->sc_reg->bw_ctl & CTL_VE) != 0;
177 break;
178
179 case FBIOSVIDEO:
180 if (*(int *)data)
181 sc->sc_reg->bw_ctl |= CTL_VE;
182 else
183 sc->sc_reg->bw_ctl &= ~CTL_VE;
184 break;
185
186 default:
187 return (ENOTTY);
188 }
189 return (0);
190 }
191
192 static void
bwtwounblank(dev)193 bwtwounblank(dev)
194 struct device *dev;
195 {
196 struct bwtwo_softc *sc = (struct bwtwo_softc *)dev;
197
198 sc->sc_reg->bw_ctl |= CTL_VE;
199 }
200
201 /*
202 * Return the address that would map the given device at the given
203 * offset, allowing for the given protection, or return -1 for error.
204 */
205 int
bwtwomap(dev,off,prot)206 bwtwomap(dev, off, prot)
207 dev_t dev;
208 int off, prot;
209 {
210 register struct bwtwo_softc *sc = bwtwocd.cd_devs[minor(dev)];
211
212 if (off & PGOFSET)
213 panic("bwtwomap");
214 if ((unsigned)off >= sc->sc_fb.fb_type.fb_size)
215 return (-1);
216 /*
217 * I turned on PMAP_NC here to disable the cache as I was
218 * getting horribly broken behaviour with it on.
219 */
220 return ((int)sc->sc_phys + off + PMAP_OBIO + PMAP_NC);
221 }
222