xref: /netbsd-src/sys/arch/atari/dev/grf.c (revision b5677b36047b601b9addaaa494a58ceae82c2a6c)
1 /*	$NetBSD: grf.c,v 1.40 2009/03/18 17:06:43 cegger Exp $	*/
2 
3 /*
4  * Copyright (c) 1995 Leo Weppelman
5  * Copyright (c) 1990 The Regents of the University of California.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * the Systems Programming Group of the University of Utah Computer
10  * Science Department.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * from: Utah $Hdr: grf.c 1.31 91/01/21$
37  *
38  *	@(#)grf.c	7.8 (Berkeley) 5/7/91
39  */
40 
41 /*
42  * Copyright (c) 1988 University of Utah.
43  *
44  * This code is derived from software contributed to Berkeley by
45  * the Systems Programming Group of the University of Utah Computer
46  * Science Department.
47  *
48  * Redistribution and use in source and binary forms, with or without
49  * modification, are permitted provided that the following conditions
50  * are met:
51  * 1. Redistributions of source code must retain the above copyright
52  *    notice, this list of conditions and the following disclaimer.
53  * 2. Redistributions in binary form must reproduce the above copyright
54  *    notice, this list of conditions and the following disclaimer in the
55  *    documentation and/or other materials provided with the distribution.
56  * 3. All advertising materials mentioning features or use of this software
57  *    must display the following acknowledgement:
58  *	This product includes software developed by the University of
59  *	California, Berkeley and its contributors.
60  * 4. Neither the name of the University nor the names of its contributors
61  *    may be used to endorse or promote products derived from this software
62  *    without specific prior written permission.
63  *
64  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
65  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
68  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74  * SUCH DAMAGE.
75  *
76  * from: Utah $Hdr: grf.c 1.31 91/01/21$
77  *
78  *	@(#)grf.c	7.8 (Berkeley) 5/7/91
79  */
80 
81 /*
82  * Graphics display driver for the Atari
83  * This is the hardware-independent portion of the driver.
84  * Hardware access is through the grf_softc->g_mode routine.
85  */
86 
87 #include <sys/cdefs.h>
88 __KERNEL_RCSID(0, "$NetBSD: grf.c,v 1.40 2009/03/18 17:06:43 cegger Exp $");
89 
90 #include <sys/param.h>
91 #include <sys/proc.h>
92 #include <sys/ioctl.h>
93 #include <sys/device.h>
94 #include <sys/file.h>
95 #include <sys/malloc.h>
96 #include <sys/conf.h>
97 #include <sys/systm.h>
98 #include <sys/vnode.h>
99 #include <sys/mman.h>
100 
101 #include <machine/cpu.h>
102 
103 #include <uvm/uvm_extern.h>
104 
105 #include <atari/atari/device.h>
106 #include <atari/dev/grfioctl.h>
107 #include <atari/dev/grfabs_reg.h>
108 #include <atari/dev/grfvar.h>
109 #include <atari/dev/itevar.h>
110 #include <atari/dev/viewioctl.h>
111 #include <atari/dev/viewvar.h>
112 
113 #include "grfcc.h"
114 #include "grfet.h"
115 #define	NGRF	(NGRFCC + NGRFET)
116 
117 #if NGRF > 0
118 
119 #include "ite.h"
120 #if NITE == 0
121 #define	ite_on(u,f)
122 #define	ite_off(u,f)
123 #define ite_reinit(d)
124 #endif
125 
126 int grfon(dev_t);
127 int grfoff(dev_t);
128 int grfsinfo(dev_t, struct grfdyninfo *);
129 
130 int grfbusprint(void *auxp, const char *);
131 int grfbusmatch(struct device *, struct cfdata *, void *);
132 void grfbusattach(struct device *, struct device *, void *);
133 
134 /*
135  * pointers to grf drivers device structs
136  */
137 struct grf_softc *grfsp[NGRF]; /* XXX */
138 
139 CFATTACH_DECL(grfbus, sizeof(struct device),
140     grfbusmatch, grfbusattach, NULL, NULL);
141 
142 extern struct cfdriver grfbus_cd;
143 
144 dev_type_open(grfopen);
145 dev_type_close(grfclose);
146 dev_type_ioctl(grfioctl);
147 dev_type_mmap(grfmmap);
148 
149 const struct cdevsw grf_cdevsw = {
150 	grfopen, grfclose, noread, nowrite, grfioctl,
151 	nostop, notty, nopoll, grfmmap, nokqfilter,
152 };
153 
154 /*
155  * only used in console init.
156  */
157 static struct cfdata *cfdata_gbus  = NULL;
158 
159 int
160 grfbusmatch(struct device *pdp, struct cfdata *cfp, void *auxp)
161 {
162 	if(strcmp(auxp, grfbus_cd.cd_name))
163 		return(0);
164 
165 	if(atari_realconfig == 0)
166 		cfdata_gbus = cfp;
167 	return(1);	/* Always there	*/
168 }
169 
170 void
171 grfbusattach(struct device *pdp, struct device *dp, void *auxp)
172 {
173     grf_auxp_t	grf_auxp;
174 
175     grf_auxp.busprint       = grfbusprint;
176     grf_auxp.from_bus_match = 1;
177 
178     if(dp == NULL) /* Console init	*/
179 	atari_config_found(cfdata_gbus, NULL, (void*)&grf_auxp, grfbusprint);
180     else {
181 	printf("\n");
182 	config_found(dp, (void*)&grf_auxp, grfbusprint);
183     }
184 }
185 
186 int
187 grfbusprint(void *auxp, const char *name)
188 {
189 	if(name == NULL)
190 		return(UNCONF);
191 	return(QUIET);
192 }
193 
194 /*ARGSUSED*/
195 int
196 grfopen(dev_t dev, int flags, int devtype, struct lwp *l)
197 {
198 	struct grf_softc *gp;
199 
200 	if (GRFUNIT(dev) >= NGRF)
201 		return(ENXIO);
202 
203 	gp = grfsp[GRFUNIT(dev)];
204 	if (gp == NULL)
205 		return(ENXIO);
206 
207 	if ((gp->g_flags & GF_ALIVE) == 0)
208 		return(ENXIO);
209 
210 	if ((gp->g_flags & (GF_OPEN|GF_EXCLUDE)) == (GF_OPEN|GF_EXCLUDE))
211 		return(EBUSY);
212 	grf_viewsync(gp);
213 
214 	return(0);
215 }
216 
217 /*ARGSUSED*/
218 int
219 grfclose(dev_t dev, int flags, int mode, struct lwp *l)
220 {
221 	struct grf_softc *gp;
222 
223 	gp = grfsp[GRFUNIT(dev)];
224 	(void)grfoff(dev);
225 	gp->g_flags &= GF_ALIVE;
226 	return(0);
227 }
228 
229 /*ARGSUSED*/
230 int
231 grfioctl(dev_t dev, u_long cmd, void * data, int flag, struct lwp *l)
232 {
233 	struct grf_softc	*gp;
234 	int			error;
235 	extern const struct cdevsw view_cdevsw;
236 
237 	gp = grfsp[GRFUNIT(dev)];
238 	error = 0;
239 
240 	switch (cmd) {
241 	case OGRFIOCGINFO:
242 	        /* argl.. no bank-member.. */
243 	  	memcpy( data, (void *)&gp->g_display, sizeof(struct grfinfo)-4);
244 		break;
245 	case GRFIOCGINFO:
246 		memcpy( data, (void *)&gp->g_display, sizeof(struct grfinfo));
247 		break;
248 	case GRFIOCON:
249 		error = grfon(dev);
250 		break;
251 	case GRFIOCOFF:
252 		error = grfoff(dev);
253 		break;
254 	case GRFIOCSINFO:
255 		error = grfsinfo(dev, (struct grfdyninfo *) data);
256 		break;
257 	case GRFGETVMODE:
258 		return(gp->g_mode(gp, GM_GRFGETVMODE, data, 0, 0));
259 	case GRFSETVMODE:
260 		error = gp->g_mode(gp, GM_GRFSETVMODE, data, 0, 0);
261 		if (error == 0 && gp->g_itedev)
262 			ite_reinit(gp->g_itedev);
263 		break;
264 	case GRFGETNUMVM:
265 		return(gp->g_mode(gp, GM_GRFGETNUMVM, data, 0, 0));
266 	/*
267 	 * these are all hardware dependant, and have to be resolved
268 	 * in the respective driver.
269 	 */
270 	case GRFIOCPUTCMAP:
271 	case GRFIOCGETCMAP:
272 	case GRFIOCSSPRITEPOS:
273 	case GRFIOCGSPRITEPOS:
274 	case GRFIOCSSPRITEINF:
275 	case GRFIOCGSPRITEINF:
276 	case GRFIOCGSPRITEMAX:
277 	default:
278 		/*
279 		 * check to see whether it's a command recognized by the
280 		 * view code.
281 		 */
282 		return((*view_cdevsw.d_ioctl)(gp->g_viewdev, cmd, data, flag,
283 					      l));
284 		error = EINVAL;
285 		break;
286 
287 	}
288 	return(error);
289 }
290 
291 /*
292  * map the contents of a graphics display card into process'
293  * memory space.
294  */
295 paddr_t
296 grfmmap(dev_t dev, off_t off, int prot)
297 {
298 	struct grf_softc	*gp;
299 	struct grfinfo		*gi;
300 	u_int			vgabase, linbase;
301 
302 	gp = grfsp[GRFUNIT(dev)];
303 	gi = &gp->g_display;
304 
305 	vgabase = gi->gd_vgabase;
306 	linbase = gi->gd_linbase;
307 
308 	/*
309 	 * control registers
310 	 */
311 	if (off >= 0 && off < gi->gd_regsize)
312 		return(((paddr_t)gi->gd_regaddr + off) >> PGSHIFT);
313 
314 	/*
315 	 * VGA memory
316 	 */
317 	if (off >= vgabase && off < (vgabase + gi->gd_vgasize))
318 		return(((paddr_t)gi->gd_vgaaddr - vgabase + off) >> PGSHIFT);
319 
320 	/*
321 	 * frame buffer
322 	 */
323 	if (off >= linbase && off < (linbase + gi->gd_fbsize))
324 		return(((paddr_t)gi->gd_fbaddr - linbase + off) >> PGSHIFT);
325 	return(-1);
326 }
327 
328 int
329 grfon(dev_t dev)
330 {
331 	struct grf_softc *gp;
332 
333 	gp = grfsp[GRFUNIT(dev)];
334 
335 	if (gp->g_flags & GF_GRFON)
336 		return(0);
337 
338 	gp->g_flags |= GF_GRFON;
339 	if (gp->g_itedev != NODEV)
340 		ite_off(gp->g_itedev, 3);
341 
342 	return(gp->g_mode(gp, (dev & GRFOVDEV) ? GM_GRFOVON : GM_GRFON,
343 							NULL, 0, 0));
344 }
345 
346 int
347 grfoff(dev_t dev)
348 {
349 	struct grf_softc *gp;
350 	int error;
351 
352 	gp = grfsp[GRFUNIT(dev)];
353 
354 	if ((gp->g_flags & GF_GRFON) == 0)
355 		return(0);
356 
357 	gp->g_flags &= ~GF_GRFON;
358 	error = gp->g_mode(gp, (dev & GRFOVDEV) ? GM_GRFOVOFF : GM_GRFOFF,
359 						NULL, 0, 0);
360 
361 	/*
362 	 * Closely tied together no X's
363 	 */
364 	if (gp->g_itedev != NODEV)
365 		ite_on(gp->g_itedev, 2);
366 
367 	return(error);
368 }
369 
370 int
371 grfsinfo(dev_t dev, struct grfdyninfo *dyninfo)
372 {
373 	struct grf_softc *gp;
374 	int error;
375 
376 	gp = grfsp[GRFUNIT(dev)];
377 	error = gp->g_mode(gp, GM_GRFCONFIG, dyninfo, 0, 0);
378 
379 	/*
380 	 * Closely tied together no X's
381 	 */
382 	if (gp->g_itedev != NODEV)
383 		ite_reinit(gp->g_itedev);
384 	return(error);
385 }
386 
387 /*
388  * Get the grf-info in sync with underlying view.
389  */
390 void
391 grf_viewsync(struct grf_softc *gp)
392 {
393 	struct view_size	vs;
394 	bmap_t			bm;
395 	struct grfinfo		*gi;
396 	extern const struct cdevsw view_cdevsw;
397 
398 	gi = &gp->g_display;
399 
400 	(*view_cdevsw.d_ioctl)(gp->g_viewdev, VIOCGBMAP, (void *)&bm,
401 			       0, NOLWP);
402 
403 	gp->g_data = (void *) 0xDeadBeaf; /* not particularly clean.. */
404 
405 	gi->gd_fbaddr  = bm.hw_address;
406 	gi->gd_fbsize  = bm.phys_mappable;
407 	gi->gd_linbase = bm.lin_base;
408 	gi->gd_regaddr = bm.hw_regs;
409 	gi->gd_regsize = bm.reg_size;
410 	gi->gd_vgaaddr = bm.vga_address;
411 	gi->gd_vgasize = bm.vga_mappable;
412 	gi->gd_vgabase = bm.vga_base;
413 
414 	if((*view_cdevsw.d_ioctl)(gp->g_viewdev, VIOCGSIZE, (void *)&vs, 0,
415 				  NOLWP)) {
416 		/*
417 		 * fill in some default values...
418 		 * XXX: Should _never_ happen
419 		 */
420 		vs.width  = 640;
421 		vs.height = 400;
422 		vs.depth  = 1;
423 	}
424 	gi->gd_colors = 1 << vs.depth;
425 	gi->gd_planes = vs.depth;
426 
427 	gi->gd_fbwidth         = vs.width;
428 	gi->gd_fbheight        = vs.height;
429 	gi->gd_dyn.gdi_fbx     = 0;
430 	gi->gd_dyn.gdi_fby     = 0;
431 	gi->gd_dyn.gdi_dwidth  = vs.width;
432 	gi->gd_dyn.gdi_dheight = vs.height;
433 	gi->gd_dyn.gdi_dx      = 0;
434 	gi->gd_dyn.gdi_dy      = 0;
435 }
436 
437 /*
438  * Change the mode of the display.
439  * Right now all we can do is grfon/grfoff.
440  * Return a UNIX error number or 0 for success.
441  */
442 /*ARGSUSED*/
443 int
444 grf_mode(struct grf_softc *gp, int cmd, void *arg, int a2, int a3)
445 {
446 	extern const struct cdevsw view_cdevsw;
447 
448 	switch (cmd) {
449 		case GM_GRFON:
450 			/*
451 			 * Get in sync with view, ite might have changed it.
452 			 */
453 			grf_viewsync(gp);
454 			(*view_cdevsw.d_ioctl)(gp->g_viewdev, VIOCDISPLAY,
455 					       NULL, 0, NOLWP);
456 			return(0);
457 	case GM_GRFOFF:
458 			(*view_cdevsw.d_ioctl)(gp->g_viewdev, VIOCREMOVE,
459 					       NULL, 0, NOLWP);
460 			return(0);
461 	case GM_GRFCONFIG:
462 	default:
463 			break;
464 	}
465 	return(EPASSTHROUGH);
466 }
467 #endif	/* NGRF > 0 */
468