xref: /netbsd-src/sys/arch/amiga/dev/grf.c (revision ae1bfcddc410612bc8c58b807e1830becb69a24c)
1 /*
2  * Copyright (c) 1988 University of Utah.
3  * Copyright (c) 1990 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * the Systems Programming Group of the University of Utah Computer
8  * Science Department.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by the University of
21  *	California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  * from: Utah $Hdr: grf.c 1.31 91/01/21$
39  *
40  *	@(#)grf.c	7.8 (Berkeley) 5/7/91
41  *	$Id: grf.c,v 1.12 1994/05/11 19:06:42 chopps Exp $
42  */
43 
44 /*
45  * Graphics display driver for the Amiga
46  * This is the hardware-independent portion of the driver.
47  * Hardware access is through the grf_softc->g_mode routine.
48  */
49 
50 #include <sys/param.h>
51 #include <sys/proc.h>
52 #include <sys/ioctl.h>
53 #include <sys/device.h>
54 #include <sys/file.h>
55 #include <sys/malloc.h>
56 #include <sys/conf.h>
57 #include <sys/systm.h>
58 #include <sys/vnode.h>
59 #include <sys/mman.h>
60 #include <vm/vm.h>
61 #include <vm/vm_kern.h>
62 #include <vm/vm_page.h>
63 #include <vm/vm_pager.h>
64 #include <machine/cpu.h>
65 #include <amiga/amiga/color.h>	/* DEBUG */
66 #include <amiga/amiga/device.h>
67 #include <amiga/dev/grfioctl.h>
68 #include <amiga/dev/grfvar.h>
69 #include <amiga/dev/itevar.h>
70 
71 #include "grf.h"
72 #if NGRF > 0
73 
74 #include "ite.h"
75 #if NITE == 0
76 #define	ite_on(u,f)
77 #define	ite_off(u,f)
78 #define ite_reinit(d)
79 #endif
80 
81 int grfopen __P((dev_t, int, int, struct proc *));
82 int grfclose __P((dev_t, int));
83 int grfioctl __P((dev_t, int, caddr_t, int, struct proc *));
84 int grfselect __P((dev_t, int));
85 int grfmap __P((dev_t, int, int));
86 
87 int grfon __P((dev_t));
88 int grfoff __P((dev_t));
89 int grfsinfo __P((dev_t, struct grfdyninfo *));
90 #ifdef BANKEDDEVPAGER
91 int grfbanked_get __P((dev_t, off_t, int));
92 int grfbanked_cur __P((dev_t));
93 int grfbanked_set __P((dev_t, int));
94 #endif
95 
96 void grfattach __P((struct device *, struct device *, void *));
97 int grfmatch __P((struct device *, struct cfdata *, void *));
98 int grfprint __P((void *, char *));
99 /*
100  * pointers to grf drivers device structs
101  */
102 struct grf_softc *grfsp[NGRF];
103 
104 
105 struct cfdriver grfcd = {
106 	NULL, "grf", grfmatch, grfattach, DV_DULL,
107 	sizeof(struct device), NULL, 0 };
108 
109 /*
110  * only used in console init.
111  */
112 static struct cfdata *cfdata;
113 
114 /*
115  * match if the unit of grf matches its perspective
116  * low level board driver.
117  */
118 int
119 grfmatch(pdp, cfp, auxp)
120 	struct device *pdp;
121 	struct cfdata *cfp;
122 	void *auxp;
123 {
124 	if (cfp->cf_unit != ((struct grf_softc *)pdp)->g_unit)
125 		return(0);
126 	cfdata = cfp;
127 	return(1);
128 }
129 
130 /*
131  * attach.. plug pointer in and print some info.
132  * then try and attach an ite to us. note: dp is NULL
133  * durring console init.
134  */
135 void
136 grfattach(pdp, dp, auxp)
137 	struct device *pdp, *dp;
138 	void *auxp;
139 {
140 	struct grf_softc *gp;
141 	int maj;
142 
143 	gp = (struct grf_softc *)pdp;
144 	grfsp[gp->g_unit] = (struct grf_softc *)pdp;
145 
146 	/*
147 	 * find our major device number
148 	 */
149 	for(maj = 0; maj < nchrdev; maj++)
150 		if (cdevsw[maj].d_open == grfopen)
151 			break;
152 
153 	gp->g_grfdev = makedev(maj, gp->g_unit);
154 	if (dp != NULL) {
155 		printf(" width %d height %d", gp->g_display.gd_dwidth,
156 		    gp->g_display.gd_dheight);
157 		if (gp->g_display.gd_colors == 2)
158 			printf(" monochrome\n");
159 		else
160 			printf(" colors %d\n", gp->g_display.gd_colors);
161 	}
162 
163 	/*
164 	 * try and attach an ite
165 	 */
166 	amiga_config_found(cfdata, dp, gp, grfprint);
167 }
168 
169 int
170 grfprint(auxp, pnp)
171 	void *auxp;
172 	char *pnp;
173 {
174 	if (pnp)
175 		printf("ite%d at %s", ((struct grf_softc *)auxp)->g_unit,
176 		    pnp);
177 	return(UNCONF);
178 }
179 
180 /*ARGSUSED*/
181 int
182 grfopen(dev, flags, devtype, p)
183 	dev_t dev;
184 	int flags, devtype;
185 	struct proc *p;
186 {
187 	struct grf_softc *gp;
188 
189 	if (GRFUNIT(dev) >= NGRF)
190 		return(ENXIO);
191 
192 	gp = grfsp[GRFUNIT(dev)];
193 
194 	if ((gp->g_flags & GF_ALIVE) == 0)
195 		return(ENXIO);
196 
197 	if ((gp->g_flags & (GF_OPEN|GF_EXCLUDE)) == (GF_OPEN|GF_EXCLUDE))
198 		return(EBUSY);
199 
200 	return(0);
201 }
202 
203 /*ARGSUSED*/
204 int
205 grfclose(dev, flags)
206 	dev_t dev;
207 	int flags;
208 {
209 	struct grf_softc *gp;
210 
211 	gp = grfsp[GRFUNIT(dev)];
212 	(void)grfoff(dev);
213 	gp->g_flags &= GF_ALIVE;
214 	return(0);
215 }
216 
217 /*ARGSUSED*/
218 int
219 grfioctl(dev, cmd, data, flag, p)
220 	dev_t dev;
221 	int cmd, flag;
222 	caddr_t data;
223 	struct proc *p;
224 {
225 	struct grf_softc *gp;
226 	int error;
227 
228 	gp = grfsp[GRFUNIT(dev)];
229 	error = 0;
230 
231 	switch (cmd) {
232 	case OGRFIOCGINFO:
233 	        /* argl.. no bank-member.. */
234 	  	bcopy((caddr_t)&gp->g_display, data, sizeof(struct grfinfo)-4);
235 		break;
236 	case GRFIOCGINFO:
237 		bcopy((caddr_t)&gp->g_display, data, sizeof(struct grfinfo));
238 		break;
239 	case GRFIOCON:
240 		error = grfon(dev);
241 		break;
242 	case GRFIOCOFF:
243 		error = grfoff(dev);
244 		break;
245 	case GRFIOCSINFO:
246 		error = grfsinfo(dev, (struct grfdyninfo *) data);
247 		break;
248 	case GRFGETVMODE:
249 		return(gp->g_mode(gp, GM_GRFGETVMODE, data));
250 	case GRFSETVMODE:
251 		error = gp->g_mode(gp, GM_GRFSETVMODE, data);
252 		if (error == 0 && gp->g_itedev)
253 			ite_reinit(gp->g_itedev);
254 		break;
255 	case GRFGETNUMVM:
256 		return(gp->g_mode(gp, GM_GRFGETNUMVM, data));
257 	/*
258 	 * these are all hardware dependant, and have to be resolved
259 	 * in the respective driver.
260 	 */
261 	case GRFIOCPUTCMAP:
262 	case GRFIOCGETCMAP:
263 	case GRFIOCSSPRITEPOS:
264 	case GRFIOCGSPRITEPOS:
265 	case GRFIOCSSPRITEINF:
266 	case GRFIOCGSPRITEINF:
267 	case GRFIOCGSPRITEMAX:
268 		return(gp->g_mode(gp, GM_GRFIOCTL, cmd, data));
269 	default:
270 		/*
271 		 * check to see whether it's a command recognized by the
272 		 * view code if the unit is 0
273 		 * XXX
274 		 */
275 		if (GRFUNIT(dev) == 0)
276 			return(viewioctl(dev, cmd, data, flag, p));
277 		error = EINVAL;
278 		break;
279 
280 	}
281 	return(error);
282 }
283 
284 /*ARGSUSED*/
285 int
286 grfselect(dev, rw)
287 	dev_t dev;
288 	int rw;
289 {
290 	if (rw == FREAD)
291 		return(0);
292 	return(1);
293 }
294 
295 /*
296  * map the contents of a graphics display card into process'
297  * memory space.
298  */
299 int
300 grfmap(dev, off, prot)
301 	dev_t dev;
302 	int off, prot;
303 {
304 	struct grf_softc *gp;
305 	struct grfinfo *gi;
306 
307 	gp = grfsp[GRFUNIT(dev)];
308 	gi = &gp->g_display;
309 
310 	/*
311 	 * control registers
312 	 */
313 	if (off >= 0 && off < gi->gd_regsize)
314 		return(((u_int)gi->gd_regaddr + off) >> PGSHIFT);
315 
316 	/*
317 	 * frame buffer
318 	 */
319 	if (off >= gi->gd_regsize && off < gi->gd_regsize+gi->gd_fbsize) {
320 		off -= gi->gd_regsize;
321 #ifdef BANKEDDEVPAGER
322 		if (gi->gd_bank_size)
323 			off %= gi->gd_bank_size;
324 #endif
325 		return(((u_int)gi->gd_fbaddr + off) >> PGSHIFT);
326 	}
327 	/* bogus */
328 	return(-1);
329 }
330 
331 int
332 grfon(dev)
333 	dev_t dev;
334 {
335 	struct grf_softc *gp;
336 
337 	gp = grfsp[GRFUNIT(dev)];
338 
339 	if (gp->g_flags & GF_GRFON)
340 		return(0);
341 
342 	gp->g_flags |= GF_GRFON;
343 	if (gp->g_itedev != NODEV)
344 		ite_off(gp->g_itedev, 3);
345 
346 	return(gp->g_mode(gp, (dev & GRFOVDEV) ? GM_GRFOVON : GM_GRFON));
347 }
348 
349 int
350 grfoff(dev)
351 	dev_t dev;
352 {
353 	struct grf_softc *gp;
354 	int error;
355 
356 	gp = grfsp[GRFUNIT(dev)];
357 
358 	if ((gp->g_flags & GF_GRFON) == 0)
359 		return(0);
360 
361 	gp->g_flags &= ~GF_GRFON;
362 	error = gp->g_mode(gp, (dev & GRFOVDEV) ? GM_GRFOVOFF : GM_GRFOFF);
363 
364 	/*
365 	 * Closely tied together no X's
366 	 */
367 	if (gp->g_itedev != NODEV)
368 		ite_on(gp->g_itedev, 2);
369 
370 	return(error);
371 }
372 
373 int
374 grfsinfo(dev, dyninfo)
375 	dev_t dev;
376 	struct grfdyninfo *dyninfo;
377 {
378 	struct grf_softc *gp;
379 	int error;
380 
381 	gp = grfsp[GRFUNIT(dev)];
382 	error = gp->g_mode(gp, GM_GRFCONFIG, dyninfo);
383 
384 	/*
385 	 * Closely tied together no X's
386 	 */
387 	if (gp->g_itedev != NODEV)
388 		ite_reinit(gp->g_itedev);
389 	return(error);
390 }
391 
392 #ifdef BANKEDDEVPAGER
393 
394 int
395 grfbanked_get (dev, off, prot)
396      dev_t dev;
397      off_t off;
398      int   prot;
399 {
400 	struct grf_softc *gp;
401 	struct grfinfo *gi;
402 	int error, bank;
403 
404 	gp = grfsp[GRFUNIT(dev)];
405 	gi = &gp->g_display;
406 
407 	off -= gi->gd_regsize;
408 	if (off < 0 || off >= gi->gd_fbsize)
409 		return -1;
410 
411 	error = gp->g_mode(gp, GM_GRFGETBANK, &bank, off, prot);
412 	return error ? -1 : bank;
413 }
414 
415 int
416 grfbanked_cur (dev)
417 	dev_t dev;
418 {
419 	struct grf_softc *gp;
420 	int error, bank;
421 
422 	gp = grfsp[GRFUNIT(dev)];
423 
424 	error = gp->g_mode(gp, GM_GRFGETCURBANK, &bank);
425 	return(error ? -1 : bank);
426 }
427 
428 int
429 grfbanked_set (dev, bank)
430 	dev_t dev;
431 	int bank;
432 {
433 	struct grf_softc *gp;
434 
435 	gp = grfsp[GRFUNIT(dev)];
436 	return(gp->g_mode(gp, GM_GRFSETBANK, bank) ? -1 : 0);
437 }
438 
439 #endif /* BANKEDDEVPAGER */
440 #endif	/* NGRF > 0 */
441