1 /*	$OpenBSD: cgthree.c,v 1.32 2006/12/03 16:38:13 miod Exp $	*/
2 /*	$NetBSD: cgthree.c,v 1.33 1997/05/24 20:16:11 pk Exp $ */
3 
4 /*
5  * Copyright (c) 2002 Miodrag Vallat.  All rights reserved.
6  * Copyright (c) 2001 Jason L. Wright (jason@thought.net)
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
22  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  *
30  * Effort sponsored in part by the Defense Advanced Research Projects
31  * Agency (DARPA) and Air Force Research Laboratory, Air Force
32  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
33  *
34  *
35  * Copyright (c) 1992, 1993
36  *	The Regents of the University of California.  All rights reserved.
37  *
38  * This software was developed by the Computer Systems Engineering group
39  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
40  * contributed to Berkeley.
41  *
42  * All advertising materials mentioning features or use of this software
43  * must display the following acknowledgement:
44  *	This product includes software developed by the University of
45  *	California, Lawrence Berkeley Laboratory.
46  *
47  * Redistribution and use in source and binary forms, with or without
48  * modification, are permitted provided that the following conditions
49  * are met:
50  * 1. Redistributions of source code must retain the above copyright
51  *    notice, this list of conditions and the following disclaimer.
52  * 2. Redistributions in binary form must reproduce the above copyright
53  *    notice, this list of conditions and the following disclaimer in the
54  *    documentation and/or other materials provided with the distribution.
55  * 3. Neither the name of the University nor the names of its contributors
56  *    may be used to endorse or promote products derived from this software
57  *    without specific prior written permission.
58  *
59  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
60  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
63  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69  * SUCH DAMAGE.
70  *
71  *	@(#)cgthree.c	8.2 (Berkeley) 10/30/93
72  */
73 
74 /*
75  * Color display (cgthree) driver.
76  * Works with the real Sun hardware, as well as various clones from Tatung,
77  * Integrix (S20), and the Vigra VS10-EK.
78  */
79 
80 #include <sys/param.h>
81 #include <sys/systm.h>
82 #include <sys/buf.h>
83 #include <sys/device.h>
84 #include <sys/ioctl.h>
85 #include <sys/malloc.h>
86 #include <sys/mman.h>
87 #include <sys/tty.h>
88 #include <sys/conf.h>
89 
90 #include <uvm/uvm_extern.h>
91 
92 #include <machine/autoconf.h>
93 #include <machine/pmap.h>
94 #include <machine/cpu.h>
95 #include <machine/conf.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 #include <sparc/dev/btreg.h>
103 #include <sparc/dev/btvar.h>
104 #include <sparc/dev/cgthreereg.h>
105 #include <sparc/dev/sbusvar.h>
106 
107 /* per-display variables */
108 struct cgthree_softc {
109 	struct	sunfb sc_sunfb;		/* common base part */
110 	struct rom_reg	sc_phys;	/* phys address description */
111 	volatile struct fbcontrol *sc_fbc;	/* Brooktree registers */
112 	union	bt_cmap sc_cmap;	/* Brooktree color map */
113 	struct intrhand sc_ih;
114 };
115 
116 void	cgthree_burner(void *, u_int, u_int);
117 int	cgthree_intr(void *);
118 int	cgthree_ioctl(void *, u_long, caddr_t, int, struct proc *);
119 static __inline__
120 void	cgthree_loadcmap_deferred(struct cgthree_softc *, u_int, u_int);
121 paddr_t	cgthree_mmap(void *, off_t, int);
122 void	cgthree_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
123 
124 struct wsdisplay_accessops cgthree_accessops = {
125 	cgthree_ioctl,
126 	cgthree_mmap,
127 	NULL,	/* alloc_screen */
128 	NULL,	/* free_screen */
129 	NULL,	/* show_screen */
130 	NULL,	/* load_font */
131 	NULL,	/* scrollback */
132 	NULL,	/* getchar */
133 	cgthree_burner,
134 	NULL	/* pollc */
135 };
136 
137 int	cgthreematch(struct device *, void *, void *);
138 void	cgthreeattach(struct device *, struct device *, void *);
139 
140 struct cfattach cgthree_ca = {
141 	sizeof (struct cgthree_softc), cgthreematch, cgthreeattach
142 };
143 
144 struct cfdriver cgthree_cd = {
145 	NULL, "cgthree", DV_DULL
146 };
147 
148 /* Video control parameters */
149 struct cg3_videoctrl {
150 	u_int8_t	sense;
151 	u_int8_t	vctrl[12];
152 } cg3_videoctrl[] = {
153 	{	/* cpd-1790 */
154 		0x31,
155 		{ 0xbb, 0x2b, 0x04, 0x14, 0xae, 0x03,
156 		  0xa8, 0x24, 0x01, 0x05, 0xff, 0x01 },
157 	},
158 	{	/* gdm-20e20 */
159 		0x41,
160 		{ 0xb7, 0x27, 0x03, 0x0f, 0xae, 0x03,
161 		  0xae, 0x2a, 0x01, 0x09, 0xff, 0x01 },
162 	},
163 	{	/* defaults, should be last */
164 		0xff,
165 		{ 0xbb, 0x2b, 0x03, 0x0b, 0xb3, 0x03,
166 		  0xaf, 0x2b, 0x02, 0x0a, 0xff, 0x01 },
167 	},
168 };
169 
170 int
cgthreematch(struct device * parent,void * vcf,void * aux)171 cgthreematch(struct device *parent, void *vcf, void *aux)
172 {
173 	struct cfdata *cf = vcf;
174 	struct confargs *ca = aux;
175 	struct romaux *ra = &ca->ca_ra;
176 
177 	if (strcmp(cf->cf_driver->cd_name, ra->ra_name) &&
178 	    strcmp("cgRDI", ra->ra_name))
179 		return (0);
180 
181 	if (ca->ca_bustype != BUS_SBUS)
182 		return (0);
183 
184 	return (1);
185 }
186 
187 void
cgthreeattach(struct device * parent,struct device * self,void * args)188 cgthreeattach(struct device *parent, struct device *self, void *args)
189 {
190 	struct cgthree_softc *sc = (struct cgthree_softc *)self;
191 	struct confargs *ca = args;
192 	int node, isrdi = 0, i;
193 	volatile struct bt_regs *bt;
194 	int isconsole = 0;
195 	char *nam;
196 
197 	printf(": ");
198 
199 	node = ca->ca_ra.ra_node;
200 
201 	if (strcmp(ca->ca_ra.ra_name, "cgRDI") == 0) {
202 		isrdi = 1;
203 		nam = "cgRDI";
204 	} else
205 		nam = getpropstring(node, "model");
206 
207 	if (nam != NULL && *nam != '\0')
208 		printf("%s, ", nam);
209 
210 	isconsole = node == fbnode;
211 
212 	sc->sc_fbc = (volatile struct fbcontrol *)
213 	    mapiodev(ca->ca_ra.ra_reg, CG3REG_REG,
214 		     sizeof(struct fbcontrol));
215 
216 	/* Transfer video magic to board, if it's not running */
217 	if (isrdi == 0 && (sc->sc_fbc->fbc_ctrl & FBC_TIMING) == 0)
218 		for (i = 0; i < sizeof(cg3_videoctrl)/sizeof(cg3_videoctrl[0]);
219 		     i++) {
220 			volatile struct fbcontrol *fbc = sc->sc_fbc;
221 			if (cg3_videoctrl[i].sense == 0xff ||
222 			    (fbc->fbc_status & FBS_MSENSE) ==
223 			     cg3_videoctrl[i].sense) {
224 				int j;
225 #ifdef DEBUG
226 				printf(" (setting video ctrl)");
227 #endif
228 				for (j = 0; j < 12; j++)
229 					fbc->fbc_vcontrol[j] =
230 						cg3_videoctrl[i].vctrl[j];
231 				fbc->fbc_ctrl |= FBC_TIMING;
232 				break;
233 			}
234 		}
235 
236 	sc->sc_phys = ca->ca_ra.ra_reg[0];
237 
238 	sc->sc_ih.ih_fun = cgthree_intr;
239 	sc->sc_ih.ih_arg = sc;
240 	intr_establish(ca->ca_ra.ra_intr[0].int_pri, &sc->sc_ih, IPL_FB);
241 
242 	/* enable video */
243 	cgthree_burner(sc, 1, 0);
244 	bt = &sc->sc_fbc->fbc_dac;
245 	BT_INIT(bt, 0);
246 
247 	fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype);
248 	sc->sc_sunfb.sf_ro.ri_bits = mapiodev(ca->ca_ra.ra_reg, CG3REG_MEM,
249 	    round_page(sc->sc_sunfb.sf_fbsize));
250 	sc->sc_sunfb.sf_ro.ri_hw = sc;
251 
252 	printf("%dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
253 
254 	/*
255 	 * If the framebuffer width is under 1024x768, which is the case for
256 	 * some clones on laptops, as well as with the VS10-EK, switch from
257 	 * the PROM font to the more adequate 8x16 font here.
258 	 * However, we need to adjust two things in this case:
259 	 * - the display row should be overrided from the current PROM metrics,
260 	 *   to prevent us from overwriting the last few lines of text.
261 	 * - if the 80x34 screen would make a large margin appear around it,
262 	 *   choose to clear the screen rather than keeping old prom output in
263 	 *   the margins.
264 	 * XXX there should be a rasops "clear margins" feature
265 	 */
266 	fbwscons_init(&sc->sc_sunfb, isconsole &&
267 	    (sc->sc_sunfb.sf_width >= 1024) ? 0 : RI_CLEAR);
268 	fbwscons_setcolormap(&sc->sc_sunfb, cgthree_setcolor);
269 
270 	if (isconsole) {
271 		fbwscons_console_init(&sc->sc_sunfb,
272 		    sc->sc_sunfb.sf_width >= 1024 ? -1 : 0);
273 	}
274 
275 	fbwscons_attach(&sc->sc_sunfb, &cgthree_accessops, isconsole);
276 }
277 
278 int
cgthree_ioctl(void * v,u_long cmd,caddr_t data,int flags,struct proc * p)279 cgthree_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
280 {
281 	struct cgthree_softc *sc = v;
282 	struct wsdisplay_fbinfo *wdf;
283 	struct wsdisplay_cmap *cm;
284 	int error;
285 
286 	switch (cmd) {
287 	case WSDISPLAYIO_GTYPE:
288 		*(u_int *)data = WSDISPLAY_TYPE_SUNCG3;
289 		break;
290 	case WSDISPLAYIO_GINFO:
291 		wdf = (struct wsdisplay_fbinfo *)data;
292 		wdf->height = sc->sc_sunfb.sf_height;
293 		wdf->width  = sc->sc_sunfb.sf_width;
294 		wdf->depth  = sc->sc_sunfb.sf_depth;
295 		wdf->cmsize = 256;
296 		break;
297 	case WSDISPLAYIO_LINEBYTES:
298 		*(u_int *)data = sc->sc_sunfb.sf_linebytes;
299 		break;
300 
301 	case WSDISPLAYIO_GETCMAP:
302 		cm = (struct wsdisplay_cmap *)data;
303 		error = bt_getcmap(&sc->sc_cmap, cm);
304 		if (error)
305 			return (error);
306 		break;
307 
308 	case WSDISPLAYIO_PUTCMAP:
309 		cm = (struct wsdisplay_cmap *)data;
310 		error = bt_putcmap(&sc->sc_cmap, cm);
311 		if (error)
312 			return (error);
313 		cgthree_loadcmap_deferred(sc, cm->index, cm->count);
314 		break;
315 
316 	case WSDISPLAYIO_SVIDEO:
317 	case WSDISPLAYIO_GVIDEO:
318 		break;
319 
320 	case WSDISPLAYIO_GCURPOS:
321 	case WSDISPLAYIO_SCURPOS:
322 	case WSDISPLAYIO_GCURMAX:
323 	case WSDISPLAYIO_GCURSOR:
324 	case WSDISPLAYIO_SCURSOR:
325 	default:
326 		return (-1);	/* not supported yet */
327         }
328 
329 	return (0);
330 }
331 
332 paddr_t
cgthree_mmap(void * v,off_t offset,int prot)333 cgthree_mmap(void *v, off_t offset, int prot)
334 {
335 	struct cgthree_softc *sc = v;
336 
337 	if (offset & PGOFSET)
338 		return (-1);
339 
340 	if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize) {
341 		return (REG2PHYS(&sc->sc_phys,
342 		    CG3REG_MEM + offset) | PMAP_NC);
343 	}
344 
345 	return (-1);
346 }
347 
348 void
cgthree_setcolor(void * v,u_int index,u_int8_t r,u_int8_t g,u_int8_t b)349 cgthree_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
350 {
351 	struct cgthree_softc *sc = v;
352 
353 	bt_setcolor(&sc->sc_cmap, &sc->sc_fbc->fbc_dac, index, r, g, b, 0);
354 }
355 
356 static __inline__ void
cgthree_loadcmap_deferred(struct cgthree_softc * sc,u_int start,u_int ncolors)357 cgthree_loadcmap_deferred(struct cgthree_softc *sc, u_int start, u_int ncolors)
358 {
359 
360 	sc->sc_fbc->fbc_ctrl |= FBC_IENAB;
361 }
362 
363 void
cgthree_burner(void * v,u_int on,u_int flags)364 cgthree_burner(void *v, u_int on, u_int flags)
365 {
366 	struct cgthree_softc *sc = v;
367 	int s;
368 
369 	s = splhigh();
370 	if (on)
371 		sc->sc_fbc->fbc_ctrl |= FBC_VENAB | FBC_TIMING;
372 	else {
373 		sc->sc_fbc->fbc_ctrl &= ~FBC_VENAB;
374 		if (flags & WSDISPLAY_BURN_VBLANK)
375 			sc->sc_fbc->fbc_ctrl &= ~FBC_TIMING;
376 	}
377 	splx(s);
378 }
379 
380 int
cgthree_intr(void * v)381 cgthree_intr(void *v)
382 {
383 	struct cgthree_softc *sc = v;
384 
385 	if (!ISSET(sc->sc_fbc->fbc_ctrl, FBC_IENAB) ||
386 	    !ISSET(sc->sc_fbc->fbc_status, FBS_INTR)) {
387 		/* Not expecting an interrupt, it's not for us. */
388 		return (0);
389 	}
390 
391 	/* Acknowledge the interrupt and disable it. */
392 	sc->sc_fbc->fbc_ctrl &= ~FBC_IENAB;
393 
394 	bt_loadcmap(&sc->sc_cmap, &sc->sc_fbc->fbc_dac, 0, 256, 0);
395 	return (1);
396 }
397