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