This source file includes following definitions.
- bwtwomatch
- bwtwoattach
- bwtwo_ioctl
- bwtwo_alloc_screen
- bwtwo_free_screen
- bwtwo_show_screen
- bwtwo_mmap
- bwtwo_is_console
- bwtwo_burner
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/errno.h>
38 #include <sys/device.h>
39 #include <sys/ioctl.h>
40 #include <sys/malloc.h>
41
42 #include <machine/bus.h>
43 #include <machine/intr.h>
44 #include <machine/autoconf.h>
45 #include <machine/openfirm.h>
46
47 #include <dev/sbus/sbusvar.h>
48 #include <dev/wscons/wsconsio.h>
49 #include <dev/wscons/wsdisplayvar.h>
50 #include <dev/rasops/rasops.h>
51 #include <machine/fbvar.h>
52
53 #define BWTWO_CTRL_OFFSET 0x400000
54 #define BWTWO_CTRL_SIZE (sizeof(u_int32_t) * 8)
55 #define BWTWO_VID_OFFSET 0x800000
56 #define BWTWO_VID_SIZE (1024 * 1024)
57
58 #define FBC_CTRL 0x10
59 #define FBC_STAT 0x11
60 #define FBC_START 0x12
61 #define FBC_END 0x13
62 #define FBC_VCTRL 0x14
63
64 #define FBC_CTRL_IENAB 0x80
65 #define FBC_CTRL_VENAB 0x40
66 #define FBC_CTRL_TIME 0x20
67 #define FBC_CTRL_CURS 0x10
68 #define FBC_CTRL_XTAL 0x0c
69 #define FBC_CTRL_XTAL_0 0x00
70 #define FBC_CTRL_XTAL_1 0x04
71 #define FBC_CTRL_XTAL_2 0x08
72 #define FBC_CTRL_XTAL_TEST 0x0c
73 #define FBC_CTRL_DIV 0x03
74 #define FBC_CTRL_DIV_1 0x00
75 #define FBC_CTRL_DIV_2 0x01
76 #define FBC_CTRL_DIV_3 0x02
77 #define FBC_CTRL_DIV_4 0x03
78
79 #define FBC_STAT_INTR 0x80
80 #define FBC_STAT_RES 0x70
81 #define FBC_STAT_RES_1024 0x10
82 #define FBC_STAT_RES_1280 0x40
83 #define FBC_STAT_RES_1152 0x30
84 #define FBC_STAT_RES_1152A 0x40
85 #define FBC_STAT_RES_1600 0x50
86 #define FBC_STAT_RES_1152B 0x60
87 #define FBC_STAT_ID 0x0f
88 #define FBC_STAT_ID_COLOR 0x01
89 #define FBC_STAT_ID_MONO 0x02
90 #define FBC_STAT_ID_MONOECL 0x03
91
92 #define FBC_READ(sc, reg) \
93 bus_space_read_1((sc)->sc_bustag, (sc)->sc_ctrl_regs, (reg))
94 #define FBC_WRITE(sc, reg, val) \
95 bus_space_write_1((sc)->sc_bustag, (sc)->sc_ctrl_regs, (reg), (val))
96
97 struct bwtwo_softc {
98 struct sunfb sc_sunfb;
99 bus_space_tag_t sc_bustag;
100 bus_addr_t sc_paddr;
101 bus_space_handle_t sc_ctrl_regs;
102 bus_space_handle_t sc_vid_regs;
103 int sc_nscreens;
104 };
105
106 int bwtwo_ioctl(void *, u_long, caddr_t, int, struct proc *);
107 int bwtwo_alloc_screen(void *, const struct wsscreen_descr *, void **,
108 int *, int *, long *);
109 void bwtwo_free_screen(void *, void *);
110 int bwtwo_show_screen(void *, void *, int, void (*cb)(void *, int, int),
111 void *);
112 paddr_t bwtwo_mmap(void *, off_t, int);
113 int bwtwo_is_console(int);
114 void bwtwo_burner(void *, u_int, u_int);
115
116 struct wsdisplay_accessops bwtwo_accessops = {
117 bwtwo_ioctl,
118 bwtwo_mmap,
119 bwtwo_alloc_screen,
120 bwtwo_free_screen,
121 bwtwo_show_screen,
122 NULL,
123 NULL,
124 NULL,
125 bwtwo_burner,
126 };
127
128 int bwtwomatch(struct device *, void *, void *);
129 void bwtwoattach(struct device *, struct device *, void *);
130
131 struct cfattach bwtwo_ca = {
132 sizeof (struct bwtwo_softc), bwtwomatch, bwtwoattach
133 };
134
135 struct cfdriver bwtwo_cd = {
136 NULL, "bwtwo", DV_DULL
137 };
138
139 int
140 bwtwomatch(parent, vcf, aux)
141 struct device *parent;
142 void *vcf, *aux;
143 {
144 struct cfdata *cf = vcf;
145 struct sbus_attach_args *sa = aux;
146
147 return (strcmp(cf->cf_driver->cd_name, sa->sa_name) == 0);
148 }
149
150 void
151 bwtwoattach(parent, self, aux)
152 struct device *parent, *self;
153 void *aux;
154 {
155 struct bwtwo_softc *sc = (struct bwtwo_softc *)self;
156 struct sbus_attach_args *sa = aux;
157 int node, console;
158 const char *nam;
159
160 node = sa->sa_node;
161 sc->sc_bustag = sa->sa_bustag;
162 sc->sc_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_slot, sa->sa_offset);
163
164 fb_setsize(&sc->sc_sunfb, 1, 1152, 900, node, 0);
165
166 if (sa->sa_nreg != 1) {
167 printf(": expected %d registers, got %d\n", 1, sa->sa_nreg);
168 goto fail;
169 }
170
171
172
173
174 if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
175 sa->sa_reg[0].sbr_offset + BWTWO_CTRL_OFFSET,
176 BWTWO_CTRL_SIZE, 0, 0, &sc->sc_ctrl_regs) != 0) {
177 printf(": cannot map ctrl registers\n");
178 goto fail_ctrl;
179 }
180
181 if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
182 sa->sa_reg[0].sbr_offset + BWTWO_VID_OFFSET,
183 sc->sc_sunfb.sf_fbsize, BUS_SPACE_MAP_LINEAR,
184 0, &sc->sc_vid_regs) != 0) {
185 printf(": cannot map vid registers\n");
186 goto fail_vid;
187 }
188
189 nam = getpropstring(node, "model");
190 if (*nam == '\0')
191 nam = sa->sa_name;
192 printf(": %s", nam);
193
194 console = bwtwo_is_console(node);
195
196 bwtwo_burner(sc, 1, 0);
197
198 printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
199
200 sc->sc_sunfb.sf_ro.ri_bits = (void *)bus_space_vaddr(sc->sc_bustag,
201 sc->sc_vid_regs);
202 sc->sc_sunfb.sf_ro.ri_hw = sc;
203 fbwscons_init(&sc->sc_sunfb, console ? 0 : RI_CLEAR);
204
205 if (console) {
206 fbwscons_console_init(&sc->sc_sunfb, -1);
207 }
208
209 fbwscons_attach(&sc->sc_sunfb, &bwtwo_accessops, console);
210
211 return;
212
213 fail_vid:
214 bus_space_unmap(sa->sa_bustag, sc->sc_ctrl_regs, BWTWO_CTRL_SIZE);
215 fail_ctrl:
216 fail:
217 ;
218 }
219
220 int
221 bwtwo_ioctl(v, cmd, data, flags, p)
222 void *v;
223 u_long cmd;
224 caddr_t data;
225 int flags;
226 struct proc *p;
227 {
228 struct bwtwo_softc *sc = v;
229 struct wsdisplay_fbinfo *wdf;
230
231 switch (cmd) {
232 case WSDISPLAYIO_GTYPE:
233 *(u_int *)data = WSDISPLAY_TYPE_SUNBW;
234 break;
235 case WSDISPLAYIO_GINFO:
236 wdf = (void *)data;
237 wdf->height = sc->sc_sunfb.sf_height;
238 wdf->width = sc->sc_sunfb.sf_width;
239 wdf->depth = sc->sc_sunfb.sf_depth;
240 wdf->cmsize = 0;
241 break;
242 case WSDISPLAYIO_LINEBYTES:
243 *(u_int *)data = sc->sc_sunfb.sf_linebytes;
244 break;
245
246 case WSDISPLAYIO_GETCMAP:
247 case WSDISPLAYIO_PUTCMAP:
248 break;
249
250 case WSDISPLAYIO_SVIDEO:
251 case WSDISPLAYIO_GVIDEO:
252 break;
253
254 case WSDISPLAYIO_GCURPOS:
255 case WSDISPLAYIO_SCURPOS:
256 case WSDISPLAYIO_GCURMAX:
257 case WSDISPLAYIO_GCURSOR:
258 case WSDISPLAYIO_SCURSOR:
259 default:
260 return -1;
261 }
262
263 return (0);
264 }
265
266 int
267 bwtwo_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
268 void *v;
269 const struct wsscreen_descr *type;
270 void **cookiep;
271 int *curxp, *curyp;
272 long *attrp;
273 {
274 struct bwtwo_softc *sc = v;
275
276 if (sc->sc_nscreens > 0)
277 return (ENOMEM);
278
279 *cookiep = &sc->sc_sunfb.sf_ro;
280 *curyp = 0;
281 *curxp = 0;
282 sc->sc_sunfb.sf_ro.ri_ops.alloc_attr(&sc->sc_sunfb.sf_ro,
283 0, 0, 0, attrp);
284 sc->sc_nscreens++;
285 return (0);
286 }
287
288 void
289 bwtwo_free_screen(v, cookie)
290 void *v;
291 void *cookie;
292 {
293 struct bwtwo_softc *sc = v;
294
295 sc->sc_nscreens--;
296 }
297
298 int
299 bwtwo_show_screen(v, cookie, waitok, cb, cbarg)
300 void *v;
301 void *cookie;
302 int waitok;
303 void (*cb)(void *, int, int);
304 void *cbarg;
305 {
306 return (0);
307 }
308
309 #define START (128 * 1024 + 128 * 1024)
310 #define NOOVERLAY (0x04000000)
311
312 paddr_t
313 bwtwo_mmap(v, offset, prot)
314 void *v;
315 off_t offset;
316 int prot;
317 {
318 struct bwtwo_softc *sc = v;
319
320 if (offset & PGOFSET)
321 return (-1);
322
323 if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize)
324 return (bus_space_mmap(sc->sc_bustag, sc->sc_paddr,
325 BWTWO_VID_OFFSET + offset, prot, BUS_SPACE_MAP_LINEAR));
326
327 return (-1);
328 }
329
330 int
331 bwtwo_is_console(node)
332 int node;
333 {
334 extern int fbnode;
335
336 return (fbnode == node);
337 }
338
339 void
340 bwtwo_burner(vsc, on, flags)
341 void *vsc;
342 u_int on, flags;
343 {
344 struct bwtwo_softc *sc = vsc;
345 int s;
346 u_int8_t fbc;
347
348 s = splhigh();
349 fbc = FBC_READ(sc, FBC_CTRL);
350 if (on)
351 fbc |= FBC_CTRL_VENAB | FBC_CTRL_TIME;
352 else {
353 fbc &= ~FBC_CTRL_VENAB;
354 if (flags & WSDISPLAY_BURN_VBLANK)
355 fbc &= ~FBC_CTRL_TIME;
356 }
357 FBC_WRITE(sc, FBC_CTRL, fbc);
358 splx(s);
359 }