1 /* $OpenBSD: bwtwo.c,v 1.34 2006/12/03 16:38:12 miod Exp $ */
2 /* $NetBSD: bwtwo.c,v 1.33 1997/05/24 20:16:02 pk Exp $ */
3
4 /*
5 * Copyright (c) 2002 Miodrag Vallat. All rights reserved.
6 * Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
7 * Copyright (c) 1992, 1993
8 * The Regents of the University of California. All rights reserved.
9 *
10 * This software was developed by the Computer Systems Engineering group
11 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
12 * contributed to Berkeley.
13 *
14 * All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by the University of
17 * California, Lawrence Berkeley Laboratory.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 * 1. Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in the
26 * documentation and/or other materials provided with the distribution.
27 * 3. Neither the name of the University nor the names of its contributors
28 * may be used to endorse or promote products derived from this software
29 * without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
32 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
35 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
40 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 * SUCH DAMAGE.
42 *
43 * @(#)bwtwo.c 8.1 (Berkeley) 6/11/93
44 */
45
46 /*
47 * black&white display (bwtwo) driver.
48 *
49 * P4 and overlay plane support by Jason R. Thorpe <thorpej@NetBSD.ORG>.
50 * Overlay plane handling hints and ideas provided by Brad Spencer.
51 */
52
53 #include <sys/param.h>
54 #include <sys/systm.h>
55 #include <sys/device.h>
56 #include <sys/ioctl.h>
57 #include <sys/malloc.h>
58 #include <sys/mman.h>
59 #include <sys/tty.h>
60 #include <sys/conf.h>
61
62 #include <uvm/uvm_extern.h>
63
64 #include <machine/autoconf.h>
65 #include <machine/eeprom.h>
66 #include <machine/ctlreg.h>
67 #include <machine/conf.h>
68 #include <sparc/sparc/asm.h>
69
70 #include <sparc/dev/btreg.h>
71 #include <sparc/dev/bwtworeg.h>
72 #include <sparc/dev/sbusvar.h>
73 #if defined(SUN4)
74 #include <sparc/dev/pfourreg.h>
75 #endif
76
77 #include <dev/wscons/wsconsio.h>
78 #include <dev/wscons/wsdisplayvar.h>
79 #include <dev/rasops/rasops.h>
80 #include <machine/fbvar.h>
81
82 #include <machine/pmap.h>
83
84 /* per-display variables */
85 struct bwtwo_softc {
86 struct sunfb sc_sunfb; /* common base part */
87 volatile struct fbcontrol *sc_reg;/* control registers */
88 struct rom_reg sc_phys; /* phys address description */
89 int sc_bustype; /* type of bus we live on */
90 int sc_pixeloffset; /* offset to framebuffer */
91 };
92
93 void bwtwo_burner(void *, u_int, u_int);
94 int bwtwo_intr(void *);
95 int bwtwo_ioctl(void *, u_long, caddr_t, int, struct proc *);
96 paddr_t bwtwo_mmap(void *, off_t, int);
97
98 struct wsdisplay_accessops bwtwo_accessops = {
99 bwtwo_ioctl,
100 bwtwo_mmap,
101 NULL, /* alloc_screen */
102 NULL, /* free_screen */
103 NULL, /* show_screen */
104 NULL, /* load_font */
105 NULL, /* scrollback */
106 NULL, /* getchar */
107 bwtwo_burner,
108 NULL /* pollc */
109 };
110
111
112 /* autoconfiguration driver */
113 void bwtwoattach(struct device *, struct device *, void *);
114 int bwtwomatch(struct device *, void *, void *);
115
116 struct cfattach bwtwo_ca = {
117 sizeof(struct bwtwo_softc), bwtwomatch, bwtwoattach
118 };
119
120 struct cfdriver bwtwo_cd = {
121 NULL, "bwtwo", DV_DULL
122 };
123
124 int
bwtwomatch(struct device * parent,void * vcf,void * aux)125 bwtwomatch(struct device *parent, void *vcf, void *aux)
126 {
127 struct cfdata *cf = vcf;
128 struct confargs *ca = aux;
129 struct romaux *ra = &ca->ca_ra;
130
131 if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
132 return (0);
133
134 #if 0
135 if (CPU_ISSUN4 && cf->cf_unit != 0)
136 return (0);
137 #endif
138
139 if (ca->ca_bustype == BUS_SBUS)
140 return (1);
141
142 /*
143 * Make sure there's hardware there.
144 */
145 if (probeget(ra->ra_vaddr, 4) == -1)
146 return (0);
147
148 switch (ca->ca_bustype) {
149 case BUS_VME16:
150 case BUS_VME32:
151 return (1);
152 case BUS_OBIO:
153 #if defined(SUN4)
154 if (CPU_ISSUN4) {
155 /*
156 * Check for a pfour framebuffer, but do not match the
157 * overlay planes for color pfour framebuffers.
158 */
159 switch (fb_pfour_id(ra->ra_vaddr)) {
160 case PFOUR_ID_BW:
161 case PFOUR_NOTPFOUR:
162 return (1);
163 case PFOUR_ID_COLOR8P1: /* bwtwo in ... */
164 case PFOUR_ID_COLOR24: /* ...overlay plane */
165 default:
166 return (0);
167 }
168 }
169 #endif
170 return (1);
171 default:
172 return (0);
173 }
174 }
175
176 void
bwtwoattach(struct device * parent,struct device * self,void * args)177 bwtwoattach(struct device *parent, struct device *self, void *args)
178 {
179 struct bwtwo_softc *sc = (struct bwtwo_softc *)self;
180 struct confargs *ca = args;
181 int node = ca->ca_ra.ra_node;
182 int isconsole = 0;
183 int sbus = 1;
184 char *nam;
185
186 printf(": ");
187
188 /*
189 * Map the control register.
190 */
191 #if defined(SUN4)
192 if (CPU_ISSUN4 && ca->ca_bustype == BUS_OBIO &&
193 fb_pfour_id(ca->ca_ra.ra_vaddr) != PFOUR_NOTPFOUR) {
194 SET(sc->sc_sunfb.sf_flags, FB_PFOUR);
195 sc->sc_sunfb.sf_pfour = (volatile u_int32_t *)
196 mapiodev(ca->ca_ra.ra_reg, 0, sizeof(u_int32_t));
197 } else
198 #endif
199 {
200 sc->sc_reg = (volatile struct fbcontrol *)
201 mapiodev(ca->ca_ra.ra_reg, BWREG_REG,
202 sizeof(struct fbcontrol));
203 }
204
205 /* Set up default pixel offset. May be changed below. */
206 sc->sc_pixeloffset = BWREG_MEM;
207
208 switch (ca->ca_bustype) {
209 case BUS_OBIO:
210 if (CPU_ISSUN4M) /* 4m has framebuffer on obio */
211 goto obp_name;
212
213 sbus = node = 0;
214 #if defined(SUN4)
215 if (ISSET(sc->sc_sunfb.sf_flags, FB_PFOUR)) {
216 nam = "p4";
217 sc->sc_pixeloffset = PFOUR_BW_OFF;
218 } else
219 #endif
220 nam = NULL;
221 break;
222
223 case BUS_VME32:
224 case BUS_VME16:
225 sbus = node = 0;
226 nam = NULL;
227 break;
228
229 case BUS_SBUS:
230 obp_name:
231 #if defined(SUN4C) || defined(SUN4M)
232 nam = getpropstring(node, "model");
233 #endif
234 break;
235 }
236
237 if (nam != NULL && *nam != '\0')
238 printf("%s, ", nam);
239
240 #if defined(SUN4)
241 if (CPU_ISSUN4) {
242 struct eeprom *eep = (struct eeprom *)eeprom_va;
243 int constype = ISSET(sc->sc_sunfb.sf_flags, FB_PFOUR) ?
244 EE_CONS_P4OPT : EE_CONS_BW;
245 /*
246 * Assume this is the console if there's no eeprom info
247 * to be found.
248 */
249 if (eep == NULL || eep->eeConsole == constype)
250 isconsole = 1;
251 else
252 /*
253 * On sun4 systems without on-board framebuffers (such as
254 * the 4/3xx models), the PROM will accept the EE_CONS_BW
255 * setting although the framebuffer is a P4.
256 * Accept this setting as well.
257 */
258 if (eep->eeConsole == EE_CONS_BW)
259 isconsole = 1;
260 }
261 #endif
262
263 if (CPU_ISSUN4COR4M)
264 isconsole = node == fbnode;
265
266 sc->sc_phys = ca->ca_ra.ra_reg[0];
267 sc->sc_bustype = ca->ca_bustype;
268
269 /* enable video */
270 bwtwo_burner(sc, 1, 0);
271
272 fb_setsize(&sc->sc_sunfb, 1, 1152, 900, node, ca->ca_bustype);
273 printf("%dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
274
275 sc->sc_sunfb.sf_ro.ri_bits = mapiodev(ca->ca_ra.ra_reg,
276 sc->sc_pixeloffset, round_page(sc->sc_sunfb.sf_fbsize));
277 sc->sc_sunfb.sf_ro.ri_hw = sc;
278 fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR);
279
280 if (isconsole) {
281 fbwscons_console_init(&sc->sc_sunfb, -1);
282 }
283
284 fbwscons_attach(&sc->sc_sunfb, &bwtwo_accessops, isconsole);
285 }
286
287 int
bwtwo_ioctl(void * v,u_long cmd,caddr_t data,int flags,struct proc * p)288 bwtwo_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
289 {
290 struct bwtwo_softc *sc = v;
291 struct wsdisplay_fbinfo *wdf;
292
293 switch (cmd) {
294 case WSDISPLAYIO_GTYPE:
295 *(u_int *)data = WSDISPLAY_TYPE_SUNBW;
296 break;
297 case WSDISPLAYIO_GINFO:
298 wdf = (struct wsdisplay_fbinfo *)data;
299 wdf->height = sc->sc_sunfb.sf_height;
300 wdf->width = sc->sc_sunfb.sf_width;
301 wdf->depth = sc->sc_sunfb.sf_depth;
302 wdf->cmsize = 0; /* no colormap */
303 break;
304 case WSDISPLAYIO_LINEBYTES:
305 *(u_int *)data = sc->sc_sunfb.sf_linebytes;
306 break;
307
308 case WSDISPLAYIO_GETCMAP:
309 case WSDISPLAYIO_PUTCMAP:
310 break;
311
312 case WSDISPLAYIO_SVIDEO:
313 case WSDISPLAYIO_GVIDEO:
314 break;
315
316 case WSDISPLAYIO_GCURPOS:
317 case WSDISPLAYIO_SCURPOS:
318 case WSDISPLAYIO_GCURMAX:
319 case WSDISPLAYIO_GCURSOR:
320 case WSDISPLAYIO_SCURSOR:
321 default:
322 return (-1); /* not supported yet */
323 }
324
325 return (0);
326 }
327
328 paddr_t
bwtwo_mmap(void * v,off_t offset,int prot)329 bwtwo_mmap(void *v, off_t offset, int prot)
330 {
331 struct bwtwo_softc *sc = v;
332
333 if (offset & PGOFSET)
334 return (-1);
335
336 if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize) {
337 return (REG2PHYS(&sc->sc_phys, sc->sc_pixeloffset + offset) |
338 PMAP_NC);
339 }
340
341 return (-1);
342 }
343
344 void
bwtwo_burner(void * v,u_int on,u_int flags)345 bwtwo_burner(void *v, u_int on, u_int flags)
346 {
347 struct bwtwo_softc *sc = v;
348 int s;
349
350 #if defined(SUN4)
351 if (CPU_ISSUN4 && (sc->sc_bustype == BUS_OBIO)) {
352 if (ISSET(sc->sc_sunfb.sf_flags, FB_PFOUR)) {
353 fb_pfour_burner(v, on, flags);
354 return;
355 }
356 if (on)
357 stba(AC_SYSENABLE, ASI_CONTROL,
358 lduba(AC_SYSENABLE, ASI_CONTROL) | SYSEN_VIDEO);
359 else
360 stba(AC_SYSENABLE, ASI_CONTROL,
361 lduba(AC_SYSENABLE, ASI_CONTROL) & ~SYSEN_VIDEO);
362
363 return;
364 }
365 #endif
366
367 s = splhigh();
368 if (on)
369 sc->sc_reg->fbc_ctrl |= FBC_VENAB | FBC_TIMING;
370 else {
371 sc->sc_reg->fbc_ctrl &= ~FBC_VENAB;
372 if (flags & WSDISPLAY_BURN_VBLANK)
373 sc->sc_reg->fbc_ctrl &= ~FBC_TIMING;
374 }
375 splx(s);
376 }
377