grf.c revision 1.1 1 /* $NetBSD: grf.c,v 1.1 1995/03/26 07:12:12 leo Exp $ */
2
3 /*
4 * Copyright (c) 1995 Leo Weppelman
5 * Copyright (c) 1988 University of Utah.
6 * Copyright (c) 1990 The Regents of the University of California.
7 * All rights reserved.
8 *
9 * This code is derived from software contributed to Berkeley by
10 * the Systems Programming Group of the University of Utah Computer
11 * Science Department.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 * must display the following acknowledgement:
23 * This product includes software developed by the University of
24 * California, Berkeley and its contributors.
25 * 4. Neither the name of the University nor the names of its contributors
26 * may be used to endorse or promote products derived from this software
27 * without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * SUCH DAMAGE.
40 *
41 * from: Utah $Hdr: grf.c 1.31 91/01/21$
42 *
43 * @(#)grf.c 7.8 (Berkeley) 5/7/91
44 */
45
46 /*
47 * Graphics display driver for the Atari
48 * This is the hardware-independent portion of the driver.
49 * Hardware access is through the grf_softc->g_mode routine.
50 */
51
52 #include <sys/param.h>
53 #include <sys/proc.h>
54 #include <sys/ioctl.h>
55 #include <sys/device.h>
56 #include <sys/file.h>
57 #include <sys/malloc.h>
58 #include <sys/conf.h>
59 #include <sys/systm.h>
60 #include <sys/vnode.h>
61 #include <sys/mman.h>
62 #include <vm/vm.h>
63 #include <vm/vm_kern.h>
64 #include <vm/vm_page.h>
65 #include <vm/vm_pager.h>
66 #include <machine/cpu.h>
67 #include <atari/atari/device.h>
68 #include <atari/dev/grfioctl.h>
69 #include <atari/dev/grfabs_reg.h>
70 #include <atari/dev/grfvar.h>
71 #include <atari/dev/itevar.h>
72 #include <atari/dev/viewioctl.h>
73 #include <atari/dev/viewvar.h>
74
75 #include "grf.h"
76 #if NGRF > 0
77
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 grfopen __P((dev_t, int, int, struct proc *));
86 int grfclose __P((dev_t, int));
87 int grfioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
88 int grfselect __P((dev_t, int));
89 int grfmap __P((dev_t, int, int));
90
91 int grfon __P((dev_t));
92 int grfoff __P((dev_t));
93 int grfsinfo __P((dev_t, struct grfdyninfo *));
94 #ifdef BANKEDDEVPAGER
95 int grfbanked_get __P((dev_t, off_t, int));
96 int grfbanked_cur __P((dev_t));
97 int grfbanked_set __P((dev_t, int));
98 #endif
99 static void grf_viewsync __P((struct grf_softc *));
100 static int grf_mode __P((struct grf_softc *, int, void *, int, int));
101
102 int grfbusprint __P((void *auxp, char *));
103 int grfbusmatch __P((struct device *, struct cfdata *, void *));
104 void grfbusattach __P((struct device *, struct device *, void *));
105
106 void grfattach __P((struct device *, struct device *, void *));
107 int grfmatch __P((struct device *, struct cfdata *, void *));
108 int grfprint __P((void *, char *));
109 /*
110 * pointers to grf drivers device structs
111 */
112 struct grf_softc *grfsp[NGRF];
113
114
115 struct cfdriver grfbuscd = {
116 NULL, "grfbus", (cfmatch_t)grfbusmatch, grfbusattach, DV_DULL,
117 sizeof(struct device)
118 };
119
120 struct cfdriver grfcd = {
121 NULL, "grf", (cfmatch_t)grfmatch, grfattach, DV_DULL,
122 sizeof(struct grf_softc), NULL, 0
123 };
124
125 /*
126 * only used in console init.
127 */
128 static struct cfdata *cfdata_gbus = NULL;
129 static struct cfdata *cfdata_grf = NULL;
130
131 int
132 grfbusmatch(pdp, cfp, auxp)
133 struct device *pdp;
134 struct cfdata *cfp;
135 void *auxp;
136 {
137 if(strcmp(auxp, grfbuscd.cd_name))
138 return(0);
139
140 if((atari_realconfig == 0) || (cfdata_gbus == NULL)) {
141 /*
142 * Probe layers we depend on
143 */
144 if(grfabs_probe() == 0)
145 return(0);
146 viewprobe();
147
148 if(atari_realconfig == 0) {
149 /*
150 * XXX: console init opens view 0
151 */
152 if(viewopen(0, 0))
153 return(0);
154 cfdata_gbus = cfp;
155 }
156 }
157 return(1); /* Always there */
158 }
159
160 void
161 grfbusattach(pdp, dp, auxp)
162 struct device *pdp, *dp;
163 void *auxp;
164 {
165 static int did_cons = 0;
166 int i;
167
168 if(dp == NULL) { /* Console init */
169 did_cons = 1;
170 i = 0;
171 atari_config_found(cfdata_gbus, NULL, (void*)&i, grfbusprint);
172 }
173 else {
174 printf("\n");
175 for(i = 0; i < NGRF; i++) {
176 /*
177 * Skip opening view[0] when we this is the console.
178 */
179 if(!did_cons || (i > 0))
180 if(viewopen(i, 0))
181 break;
182 config_found(dp, (void*)&i, grfbusprint);
183 }
184 }
185 }
186
187 int
188 grfbusprint(auxp, name)
189 void *auxp;
190 char *name;
191 {
192 if(name == NULL)
193 return(UNCONF);
194 return(QUIET);
195 }
196
197
198 int
199 grfmatch(pdp, cfp, auxp)
200 struct device *pdp;
201 struct cfdata *cfp;
202 void *auxp;
203 {
204 int unit = *(int*)auxp;
205
206 /*
207 * Match only on unit indicated by grfbus attach.
208 */
209 if(cfp->cf_unit != unit)
210 return(0);
211
212 cfdata_grf = cfp;
213 return(1);
214 }
215
216 /*
217 * attach: initialize the grf-structure and try to attach an ite to us.
218 * note : dp is NULL during early console init.
219 */
220 void
221 grfattach(pdp, dp, auxp)
222 struct device *pdp, *dp;
223 void *auxp;
224 {
225 extern struct view_softc views[];
226 static struct grf_softc congrf;
227 struct grf_softc *gp;
228 int maj;
229
230 /*
231 * find our major device number
232 */
233 for(maj = 0; maj < nchrdev; maj++)
234 if (cdevsw[maj].d_open == grfopen)
235 break;
236
237 /*
238 * Handle exeption case: early console init
239 */
240 if(dp == NULL) {
241 congrf.g_unit = 0;
242 congrf.g_grfdev = makedev(maj, 0);
243 congrf.g_flags = GF_ALIVE;
244 congrf.g_mode = grf_mode;
245 congrf.g_conpri = grfcc_cnprobe();
246 congrf.g_view = views[0].view; /* XXX */
247 congrf.g_viewdev = congrf.g_unit;
248 grfcc_iteinit(&congrf);
249 grf_viewsync(&congrf);
250
251 /* Attach console ite */
252 atari_config_found(cfdata_grf, NULL, &congrf, grfprint);
253 return;
254 }
255
256 gp = (struct grf_softc *)dp;
257 gp->g_unit = gp->g_device.dv_unit;
258 grfsp[gp->g_unit] = gp;
259
260 if((cfdata_grf != NULL) && (gp->g_unit == 0)) {
261 /*
262 * We inited earlier just copy the info, take care
263 * not to copy the device struct though.
264 */
265 bcopy(&congrf.g_display, &gp->g_display,
266 (char *)&gp[1] - (char *)&gp->g_display);
267 }
268 else {
269 gp->g_grfdev = makedev(maj, gp->g_unit);
270 gp->g_flags = GF_ALIVE;
271 gp->g_mode = grf_mode;
272 gp->g_conpri = 0;
273 gp->g_view = views[gp->g_unit].view; /* XXX */
274 gp->g_viewdev = gp->g_unit;
275 grfcc_iteinit(gp);
276 grf_viewsync(gp);
277 }
278
279 printf(": width %d height %d", gp->g_display.gd_dwidth,
280 gp->g_display.gd_dheight);
281 if(gp->g_display.gd_colors == 2)
282 printf(" monochrome\n");
283 else printf(" colors %d\n", gp->g_display.gd_colors);
284
285 /*
286 * try and attach an ite
287 */
288 config_found(dp, gp, grfprint);
289 }
290
291 int
292 grfprint(auxp, pnp)
293 void *auxp;
294 char *pnp;
295 {
296 if(pnp)
297 printf("ite at %s", pnp);
298 return(UNCONF);
299 }
300
301 /*ARGSUSED*/
302 int
303 grfopen(dev, flags, devtype, p)
304 dev_t dev;
305 int flags, devtype;
306 struct proc *p;
307 {
308 struct grf_softc *gp;
309
310 if (GRFUNIT(dev) >= NGRF)
311 return(ENXIO);
312
313 gp = grfsp[GRFUNIT(dev)];
314
315 if ((gp->g_flags & GF_ALIVE) == 0)
316 return(ENXIO);
317
318 if ((gp->g_flags & (GF_OPEN|GF_EXCLUDE)) == (GF_OPEN|GF_EXCLUDE))
319 return(EBUSY);
320
321 return(0);
322 }
323
324 /*ARGSUSED*/
325 int
326 grfclose(dev, flags)
327 dev_t dev;
328 int flags;
329 {
330 struct grf_softc *gp;
331
332 gp = grfsp[GRFUNIT(dev)];
333 (void)grfoff(dev);
334 gp->g_flags &= GF_ALIVE;
335 return(0);
336 }
337
338 /*ARGSUSED*/
339 int
340 grfioctl(dev, cmd, data, flag, p)
341 dev_t dev;
342 u_long cmd;
343 int flag;
344 caddr_t data;
345 struct proc *p;
346 {
347 struct grf_softc *gp;
348 int error;
349
350 gp = grfsp[GRFUNIT(dev)];
351 error = 0;
352
353 switch (cmd) {
354 case OGRFIOCGINFO:
355 /* argl.. no bank-member.. */
356 bcopy((caddr_t)&gp->g_display, data, sizeof(struct grfinfo)-4);
357 break;
358 case GRFIOCGINFO:
359 bcopy((caddr_t)&gp->g_display, data, sizeof(struct grfinfo));
360 break;
361 case GRFIOCON:
362 error = grfon(dev);
363 break;
364 case GRFIOCOFF:
365 error = grfoff(dev);
366 break;
367 case GRFIOCSINFO:
368 error = grfsinfo(dev, (struct grfdyninfo *) data);
369 break;
370 case GRFGETVMODE:
371 return(gp->g_mode(gp, GM_GRFGETVMODE, data));
372 case GRFSETVMODE:
373 error = gp->g_mode(gp, GM_GRFSETVMODE, data);
374 if (error == 0 && gp->g_itedev)
375 ite_reinit(gp->g_itedev);
376 break;
377 case GRFGETNUMVM:
378 return(gp->g_mode(gp, GM_GRFGETNUMVM, data));
379 /*
380 * these are all hardware dependant, and have to be resolved
381 * in the respective driver.
382 */
383 case GRFIOCPUTCMAP:
384 case GRFIOCGETCMAP:
385 case GRFIOCSSPRITEPOS:
386 case GRFIOCGSPRITEPOS:
387 case GRFIOCSSPRITEINF:
388 case GRFIOCGSPRITEINF:
389 case GRFIOCGSPRITEMAX:
390 default:
391 /*
392 * check to see whether it's a command recognized by the
393 * view code.
394 */
395 if(gp->g_view != NULL)
396 return(viewioctl(gp->g_viewdev, cmd, data, flag, p));
397 error = EINVAL;
398 break;
399
400 }
401 return(error);
402 }
403
404 /*ARGSUSED*/
405 int
406 grfselect(dev, rw)
407 dev_t dev;
408 int rw;
409 {
410 if (rw == FREAD)
411 return(0);
412 return(1);
413 }
414
415 /*
416 * map the contents of a graphics display card into process'
417 * memory space.
418 */
419 int
420 grfmap(dev, off, prot)
421 dev_t dev;
422 int off, prot;
423 {
424 panic("No grfmap\n"); /* LWP */
425 }
426
427 int
428 grfon(dev)
429 dev_t dev;
430 {
431 struct grf_softc *gp;
432
433 gp = grfsp[GRFUNIT(dev)];
434
435 if (gp->g_flags & GF_GRFON)
436 return(0);
437
438 gp->g_flags |= GF_GRFON;
439 if (gp->g_itedev != NODEV)
440 ite_off(gp->g_itedev, 3);
441
442 return(gp->g_mode(gp, (dev & GRFOVDEV) ? GM_GRFOVON : GM_GRFON));
443 }
444
445 int
446 grfoff(dev)
447 dev_t dev;
448 {
449 struct grf_softc *gp;
450 int error;
451
452 gp = grfsp[GRFUNIT(dev)];
453
454 if ((gp->g_flags & GF_GRFON) == 0)
455 return(0);
456
457 gp->g_flags &= ~GF_GRFON;
458 error = gp->g_mode(gp, (dev & GRFOVDEV) ? GM_GRFOVOFF : GM_GRFOFF);
459
460 /*
461 * Closely tied together no X's
462 */
463 if (gp->g_itedev != NODEV)
464 ite_on(gp->g_itedev, 2);
465
466 return(error);
467 }
468
469 int
470 grfsinfo(dev, dyninfo)
471 dev_t dev;
472 struct grfdyninfo *dyninfo;
473 {
474 struct grf_softc *gp;
475 int error;
476
477 gp = grfsp[GRFUNIT(dev)];
478 error = gp->g_mode(gp, GM_GRFCONFIG, dyninfo);
479
480 /*
481 * Closely tied together no X's
482 */
483 if (gp->g_itedev != NODEV)
484 ite_reinit(gp->g_itedev);
485 return(error);
486 }
487
488 /*
489 * Get the grf-info in sync with underlying view.
490 */
491 static void
492 grf_viewsync(gp)
493 struct grf_softc *gp;
494 {
495 struct view_size vs;
496 bmap_t bm;
497 struct grfinfo *gi;
498
499 gi = &gp->g_display;
500
501 viewioctl(gp->g_viewdev, VIOCGBMAP, &bm, 0, -1);
502
503 gp->g_data = (caddr_t) 0xDeadBeaf; /* not particularly clean.. */
504
505 gi->gd_fbaddr = bm.hw_address;
506 gi->gd_fbsize = bm.depth*bm.bytes_per_row*bm.rows;
507
508 if(viewioctl(gp->g_viewdev, VIOCGSIZE, &vs, 0, -1)) {
509 /*
510 * fill in some default values...
511 * XXX: Should _never_ happen
512 */
513 vs.width = 640;
514 vs.height = 400;
515 vs.depth = 2;
516 }
517 gi->gd_colors = 1 << vs.depth;
518 gi->gd_planes = vs.depth;
519
520 gi->gd_fbwidth = vs.width;
521 gi->gd_fbheight = vs.height;
522 gi->gd_dyn.gdi_fbx = 0;
523 gi->gd_dyn.gdi_fby = 0;
524 gi->gd_dyn.gdi_dwidth = vs.width;
525 gi->gd_dyn.gdi_dheight = vs.height;
526 gi->gd_dyn.gdi_dx = 0;
527 gi->gd_dyn.gdi_dy = 0;
528 }
529
530 /*
531 * Change the mode of the display.
532 * Right now all we can do is grfon/grfoff.
533 * Return a UNIX error number or 0 for success.
534 */
535 /*ARGSUSED*/
536 static int
537 grf_mode(gp, cmd, arg, a2, a3)
538 struct grf_softc *gp;
539 int cmd, a2, a3;
540 void *arg;
541 {
542 switch (cmd) {
543 case GM_GRFON:
544 /*
545 * Get in sync with view, ite might have changed it.
546 */
547 grf_viewsync(gp);
548 viewioctl(gp->g_viewdev, VIOCDISPLAY, NULL, 0, -1);
549 return(0);
550 case GM_GRFOFF:
551 viewioctl(gp->g_viewdev, VIOCREMOVE, NULL, 0, -1);
552 return(0);
553 case GM_GRFCONFIG:
554 default:
555 break;
556 }
557 return(EINVAL);
558 }
559 #endif /* NGRF > 0 */
560