Annotation of sys/arch/sparc/dev/cgtwo.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: cgtwo.c,v 1.36 2006/12/03 16:40:06 miod Exp $ */
2: /* $NetBSD: cgtwo.c,v 1.22 1997/05/24 20:16:12 pk Exp $ */
3:
4: /*
5: * Copyright (c) 2002 Miodrag Vallat. All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26: * POSSIBILITY OF SUCH DAMAGE.
27: *
28: *
29: * Copyright (c) 1992, 1993
30: * The Regents of the University of California. All rights reserved.
31: *
32: * This software was developed by the Computer Systems Engineering group
33: * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
34: * contributed to Berkeley.
35: *
36: * All advertising materials mentioning features or use of this software
37: * must display the following acknowledgement:
38: * This product includes software developed by the University of
39: * California, Lawrence Berkeley Laboratory.
40: *
41: * Redistribution and use in source and binary forms, with or without
42: * modification, are permitted provided that the following conditions
43: * are met:
44: * 1. Redistributions of source code must retain the above copyright
45: * notice, this list of conditions and the following disclaimer.
46: * 2. Redistributions in binary form must reproduce the above copyright
47: * notice, this list of conditions and the following disclaimer in the
48: * documentation and/or other materials provided with the distribution.
49: * 3. Neither the name of the University nor the names of its contributors
50: * may be used to endorse or promote products derived from this software
51: * without specific prior written permission.
52: *
53: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63: * SUCH DAMAGE.
64: *
65: * from: @(#)cgthree.c 8.2 (Berkeley) 10/30/93
66: */
67:
68: /*
69: * color display (cgtwo) driver.
70: *
71: * Does not handle interrupts, even though they can occur.
72: *
73: * XXX should defer colormap updates to vertical retrace interrupts
74: */
75:
76: #include <sys/param.h>
77: #include <sys/systm.h>
78: #include <sys/buf.h>
79: #include <sys/device.h>
80: #include <sys/ioctl.h>
81: #include <sys/malloc.h>
82: #include <sys/mman.h>
83: #include <sys/tty.h>
84: #include <sys/conf.h>
85:
86: #include <uvm/uvm_extern.h>
87:
88: #include <machine/autoconf.h>
89: #include <machine/pmap.h>
90: #if defined(SUN4)
91: #include <machine/eeprom.h>
92: #endif
93: #include <machine/conf.h>
94:
95: #include <sparc/dev/cgtworeg.h>
96:
97: #include <dev/wscons/wsconsio.h>
98: #include <dev/wscons/wsdisplayvar.h>
99: #include <dev/rasops/rasops.h>
100: #include <machine/fbvar.h>
101:
102:
103: /* per-display variables */
104: struct cgtwo_softc {
105: struct sunfb sc_sunfb; /* common base part */
106: struct rom_reg sc_phys; /* display RAM (phys addr) */
107: volatile struct cg2statusreg *sc_reg; /* CG2 control registers */
108: volatile u_short *sc_ppmask;
109: volatile u_short *sc_cmap;
110: #define sc_redmap(cmap) ((cmap))
111: #define sc_greenmap(cmap) ((cmap) + CG2_CMSIZE)
112: #define sc_bluemap(cmap) ((cmap) + 2 * CG2_CMSIZE)
113: };
114:
115: void cgtwo_burner(void *, u_int, u_int);
116: int cgtwo_getcmap(struct cgtwo_softc *, struct wsdisplay_cmap *);
117: int cgtwo_ioctl(void *, u_long, caddr_t, int, struct proc *);
118: paddr_t cgtwo_mmap(void *, off_t, int);
119: int cgtwo_putcmap(struct cgtwo_softc *, struct wsdisplay_cmap *);
120: void cgtwo_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
121:
122: struct wsdisplay_accessops cgtwo_accessops = {
123: cgtwo_ioctl,
124: cgtwo_mmap,
125: NULL, /* alloc_screen */
126: NULL, /* free_screen */
127: NULL, /* show_screen */
128: NULL, /* load_font */
129: NULL, /* scrollback */
130: NULL, /* getchar */
131: cgtwo_burner,
132: NULL /* pollc */
133: };
134:
135: int cgtwomatch(struct device *, void *, void *);
136: void cgtwoattach(struct device *, struct device *, void *);
137:
138: struct cfattach cgtwo_ca = {
139: sizeof(struct cgtwo_softc), cgtwomatch, cgtwoattach
140: };
141:
142: struct cfdriver cgtwo_cd = {
143: NULL, "cgtwo", DV_DULL
144: };
145:
146: int
147: cgtwomatch(struct device *parent, void *vcf, void *aux)
148: {
149: struct cfdata *cf = vcf;
150: struct confargs *ca = aux;
151: struct romaux *ra = &ca->ca_ra;
152: caddr_t tmp;
153:
154: if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
155: return (0);
156:
157: if (!CPU_ISSUN4 || ca->ca_bustype != BUS_VME16)
158: return (0);
159:
160: /* XXX - Must do our own mapping at CG2_CTLREG_OFF */
161: bus_untmp();
162: tmp = (caddr_t)mapdev(ra->ra_reg, TMPMAP_VA, CG2_CTLREG_OFF, NBPG);
163: if (probeget(tmp, 2) != -1)
164: return (1);
165:
166: return (0);
167: }
168:
169: void
170: cgtwoattach(struct device *parent, struct device *self, void *args)
171: {
172: struct cgtwo_softc *sc = (struct cgtwo_softc *)self;
173: struct confargs *ca = args;
174: int node = 0;
175: int isconsole = 0;
176:
177: if (CPU_ISSUN4) {
178: struct eeprom *eep = (struct eeprom *)eeprom_va;
179: /*
180: * Assume this is the console if there's no eeprom info
181: * to be found.
182: */
183: if (eep == NULL || eep->eeConsole == EE_CONS_COLOR)
184: isconsole = 1;
185: }
186:
187: /*
188: * When the ROM has mapped in a cgtwo display, the address
189: * maps only the video RAM, so in any case we have to map the
190: * registers ourselves.
191: */
192: sc->sc_phys = ca->ca_ra.ra_reg[0];
193: /* Apparently, the pixels are 32-bit data space */
194: sc->sc_phys.rr_iospace = PMAP_VME32;
195:
196: sc->sc_reg = (volatile struct cg2statusreg *)
197: mapiodev(ca->ca_ra.ra_reg,
198: CG2_ROPMEM_OFF + offsetof(struct cg2fb, status.reg),
199: sizeof(struct cg2statusreg));
200:
201: sc->sc_ppmask = (volatile u_short *)
202: mapiodev(ca->ca_ra.ra_reg,
203: CG2_ROPMEM_OFF + offsetof(struct cg2fb, ppmask.reg),
204: sizeof(u_short));
205:
206: sc->sc_cmap = (volatile u_short *)
207: mapiodev(ca->ca_ra.ra_reg,
208: CG2_ROPMEM_OFF + offsetof(struct cg2fb, redmap),
209: 3 * CG2_CMSIZE * sizeof(u_short));
210:
211: /* enable video */
212: *sc->sc_ppmask = 0xffff; /* enable all color planes... */
213: cgtwo_burner(sc, 1, 0); /* ... and video signals */
214:
215: fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype);
216: sc->sc_sunfb.sf_ro.ri_bits = mapiodev(&sc->sc_phys, CG2_PIXMAP_OFF,
217: round_page(sc->sc_sunfb.sf_fbsize));
218: sc->sc_sunfb.sf_ro.ri_hw = sc;
219: fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR);
220: fbwscons_setcolormap(&sc->sc_sunfb, cgtwo_setcolor);
221:
222: printf(": %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
223:
224: if (isconsole) {
225: fbwscons_console_init(&sc->sc_sunfb, -1);
226: }
227:
228: fbwscons_attach(&sc->sc_sunfb, &cgtwo_accessops, isconsole);
229: }
230:
231: int
232: cgtwo_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
233: {
234: struct cgtwo_softc *sc = v;
235: struct wsdisplay_fbinfo *wdf;
236: struct wsdisplay_cmap *cm;
237: int error;
238:
239: switch (cmd) {
240: case WSDISPLAYIO_GTYPE:
241: *(u_int *)data = WSDISPLAY_TYPE_SUNCG2;
242: break;
243: case WSDISPLAYIO_GINFO:
244: wdf = (struct wsdisplay_fbinfo *)data;
245: wdf->height = sc->sc_sunfb.sf_height;
246: wdf->width = sc->sc_sunfb.sf_width;
247: wdf->depth = sc->sc_sunfb.sf_depth;
248: wdf->cmsize = CG2_CMSIZE;
249: break;
250: case WSDISPLAYIO_LINEBYTES:
251: *(u_int *)data = sc->sc_sunfb.sf_linebytes;
252: break;
253:
254: case WSDISPLAYIO_GETCMAP:
255: cm = (struct wsdisplay_cmap *)data;
256: error = cgtwo_getcmap(sc, cm);
257: if (error)
258: return (error);
259: break;
260:
261: case WSDISPLAYIO_PUTCMAP:
262: cm = (struct wsdisplay_cmap *)data;
263: error = cgtwo_putcmap(sc, cm);
264: if (error)
265: return (error);
266: break;
267:
268: case WSDISPLAYIO_SVIDEO:
269: case WSDISPLAYIO_GVIDEO:
270: break;
271:
272: case WSDISPLAYIO_GCURPOS:
273: case WSDISPLAYIO_SCURPOS:
274: case WSDISPLAYIO_GCURMAX:
275: case WSDISPLAYIO_GCURSOR:
276: case WSDISPLAYIO_SCURSOR:
277: default:
278: return (-1); /* not supported yet */
279: }
280:
281: return (0);
282: }
283:
284: paddr_t
285: cgtwo_mmap(void *v, off_t offset, int prot)
286: {
287: struct cgtwo_softc *sc = v;
288:
289: if (offset & PGOFSET)
290: return (-1);
291:
292: if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize) {
293: return (REG2PHYS(&sc->sc_phys,
294: CG2_PIXMAP_OFF + offset) | PMAP_NC);
295: }
296:
297: return (-1);
298: }
299:
300: void
301: cgtwo_burner(void *v, u_int on, u_int flags)
302: {
303: struct cgtwo_softc *sc = v;
304: int s;
305:
306: s = splhigh();
307: if (on)
308: sc->sc_reg->video_enab = 1;
309: else
310: sc->sc_reg->video_enab = 0;
311: splx(s);
312: }
313:
314: int
315: cgtwo_getcmap(struct cgtwo_softc *sc, struct wsdisplay_cmap *cmap)
316: {
317: u_int index = cmap->index, count = cmap->count, i;
318: u_char red[CG2_CMSIZE], green[CG2_CMSIZE], blue[CG2_CMSIZE];
319: volatile u_short *hwcmap = sc->sc_cmap;
320: int error;
321: volatile u_short *p;
322:
323:
324: if (index >= CG2_CMSIZE || count >= CG2_CMSIZE - index)
325: return (EINVAL);
326:
327: while (sc->sc_reg->retrace == 0)
328: DELAY(1);
329:
330: sc->sc_reg->update_cmap = 0;
331:
332: /* Copy hardware to local arrays. */
333: p = &sc_redmap(hwcmap)[index];
334: for (i = 0; i < count; i++)
335: red[i] = *p++;
336: p = &sc_greenmap(hwcmap)[index];
337: for (i = 0; i < count; i++)
338: green[i] = *p++;
339: p = &sc_bluemap(hwcmap)[index];
340: for (i = 0; i < count; i++)
341: blue[i] = *p++;
342:
343: sc->sc_reg->update_cmap = 1;
344:
345: /* Copy local arrays to user space. */
346: if ((error = copyout(red, cmap->red, count)) != 0)
347: return (error);
348: if ((error = copyout(green, cmap->green, count)) != 0)
349: return (error);
350: if ((error = copyout(blue, cmap->blue, count)) != 0)
351: return (error);
352:
353: return (0);
354: }
355:
356: int
357: cgtwo_putcmap(struct cgtwo_softc *sc, struct wsdisplay_cmap *cmap)
358: {
359: u_int index = cmap->index, count = cmap->count, i;
360: u_char red[CG2_CMSIZE], green[CG2_CMSIZE], blue[CG2_CMSIZE];
361: volatile u_short *hwcmap = sc->sc_cmap;
362: int error;
363: volatile u_short *p;
364:
365: if (index >= CG2_CMSIZE || count >= CG2_CMSIZE - index)
366: return (EINVAL);
367:
368: /* Copy from user space to local arrays. */
369: if ((error = copyin(cmap->red, red, count)) != 0)
370: return (error);
371: if ((error = copyin(cmap->green, green, count)) != 0)
372: return (error);
373: if ((error = copyin(cmap->blue, blue, count)) != 0)
374: return (error);
375:
376: while (sc->sc_reg->retrace == 0)
377: DELAY(1);
378:
379: sc->sc_reg->update_cmap = 0;
380:
381: /* Copy from local arrays to hardware. */
382: p = &sc_redmap(hwcmap)[index];
383: for (i = 0; i < count; i++)
384: *p++ = red[i];
385: p = &sc_greenmap(hwcmap)[index];
386: for (i = 0; i < count; i++)
387: *p++ = green[i];
388: p = &sc_bluemap(hwcmap)[index];
389: for (i = 0; i < count; i++)
390: *p++ = blue[i];
391:
392: sc->sc_reg->update_cmap = 1;
393:
394: return (0);
395: }
396:
397: void
398: cgtwo_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
399: {
400: struct cgtwo_softc *sc = v;
401:
402: while (sc->sc_reg->retrace == 0)
403: DELAY(1);
404:
405: sc->sc_reg->update_cmap = 0;
406:
407: sc_redmap(sc->sc_cmap)[index] = r;
408: sc_greenmap(sc->sc_cmap)[index] = g;
409: sc_bluemap(sc->sc_cmap)[index] = b;
410:
411: sc->sc_reg->update_cmap = 1;
412: }
CVSweb