grf.c revision 1.36 1 /* $NetBSD: grf.c,v 1.36 2007/03/04 05:59:40 christos 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.36 2007/03/04 05:59:40 christos 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 __P((dev_t));
127 int grfoff __P((dev_t));
128 int grfsinfo __P((dev_t, struct grfdyninfo *));
129
130 int grfbusprint __P((void *auxp, const char *));
131 int grfbusmatch __P((struct device *, struct cfdata *, void *));
132 void grfbusattach __P((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(pdp, cfp, auxp)
161 struct device *pdp;
162 struct cfdata *cfp;
163 void *auxp;
164 {
165 if(strcmp(auxp, grfbus_cd.cd_name))
166 return(0);
167
168 if(atari_realconfig == 0)
169 cfdata_gbus = cfp;
170 return(1); /* Always there */
171 }
172
173 void
174 grfbusattach(pdp, dp, auxp)
175 struct device *pdp, *dp;
176 void *auxp;
177 {
178 grf_auxp_t grf_auxp;
179
180 grf_auxp.busprint = grfbusprint;
181 grf_auxp.from_bus_match = 1;
182
183 if(dp == NULL) /* Console init */
184 atari_config_found(cfdata_gbus, NULL, (void*)&grf_auxp, grfbusprint);
185 else {
186 printf("\n");
187 config_found(dp, (void*)&grf_auxp, grfbusprint);
188 }
189 }
190
191 int
192 grfbusprint(auxp, name)
193 void *auxp;
194 const char *name;
195 {
196 if(name == NULL)
197 return(UNCONF);
198 return(QUIET);
199 }
200
201 /*ARGSUSED*/
202 int
203 grfopen(dev, flags, devtype, l)
204 dev_t dev;
205 int flags, devtype;
206 struct lwp *l;
207 {
208 struct grf_softc *gp;
209
210 if (GRFUNIT(dev) >= NGRF)
211 return(ENXIO);
212
213 gp = grfsp[GRFUNIT(dev)];
214 if (gp == NULL)
215 return(ENXIO);
216
217 if ((gp->g_flags & GF_ALIVE) == 0)
218 return(ENXIO);
219
220 if ((gp->g_flags & (GF_OPEN|GF_EXCLUDE)) == (GF_OPEN|GF_EXCLUDE))
221 return(EBUSY);
222 grf_viewsync(gp);
223
224 return(0);
225 }
226
227 /*ARGSUSED*/
228 int
229 grfclose(dev, flags, mode, l)
230 dev_t dev;
231 int flags;
232 int mode;
233 struct lwp *l;
234 {
235 struct grf_softc *gp;
236
237 gp = grfsp[GRFUNIT(dev)];
238 (void)grfoff(dev);
239 gp->g_flags &= GF_ALIVE;
240 return(0);
241 }
242
243 /*ARGSUSED*/
244 int
245 grfioctl(dev, cmd, data, flag, l)
246 dev_t dev;
247 u_long cmd;
248 int flag;
249 void * data;
250 struct lwp *l;
251 {
252 struct grf_softc *gp;
253 int error;
254 extern const struct cdevsw view_cdevsw;
255
256 gp = grfsp[GRFUNIT(dev)];
257 error = 0;
258
259 switch (cmd) {
260 case OGRFIOCGINFO:
261 /* argl.. no bank-member.. */
262 bcopy((void *)&gp->g_display, data, sizeof(struct grfinfo)-4);
263 break;
264 case GRFIOCGINFO:
265 bcopy((void *)&gp->g_display, data, sizeof(struct grfinfo));
266 break;
267 case GRFIOCON:
268 error = grfon(dev);
269 break;
270 case GRFIOCOFF:
271 error = grfoff(dev);
272 break;
273 case GRFIOCSINFO:
274 error = grfsinfo(dev, (struct grfdyninfo *) data);
275 break;
276 case GRFGETVMODE:
277 return(gp->g_mode(gp, GM_GRFGETVMODE, data, 0, 0));
278 case GRFSETVMODE:
279 error = gp->g_mode(gp, GM_GRFSETVMODE, data, 0, 0);
280 if (error == 0 && gp->g_itedev)
281 ite_reinit(gp->g_itedev);
282 break;
283 case GRFGETNUMVM:
284 return(gp->g_mode(gp, GM_GRFGETNUMVM, data, 0, 0));
285 /*
286 * these are all hardware dependant, and have to be resolved
287 * in the respective driver.
288 */
289 case GRFIOCPUTCMAP:
290 case GRFIOCGETCMAP:
291 case GRFIOCSSPRITEPOS:
292 case GRFIOCGSPRITEPOS:
293 case GRFIOCSSPRITEINF:
294 case GRFIOCGSPRITEINF:
295 case GRFIOCGSPRITEMAX:
296 default:
297 /*
298 * check to see whether it's a command recognized by the
299 * view code.
300 */
301 return((*view_cdevsw.d_ioctl)(gp->g_viewdev, cmd, data, flag,
302 l));
303 error = EINVAL;
304 break;
305
306 }
307 return(error);
308 }
309
310 /*
311 * map the contents of a graphics display card into process'
312 * memory space.
313 */
314 paddr_t
315 grfmmap(dev, off, prot)
316 dev_t dev;
317 off_t off;
318 int prot;
319 {
320 struct grf_softc *gp;
321 struct grfinfo *gi;
322 u_int vgabase, linbase;
323
324 gp = grfsp[GRFUNIT(dev)];
325 gi = &gp->g_display;
326
327 vgabase = gi->gd_vgabase;
328 linbase = gi->gd_linbase;
329
330 /*
331 * control registers
332 */
333 if (off >= 0 && off < gi->gd_regsize)
334 return(((paddr_t)gi->gd_regaddr + off) >> PGSHIFT);
335
336 /*
337 * VGA memory
338 */
339 if (off >= vgabase && off < (vgabase + gi->gd_vgasize))
340 return(((paddr_t)gi->gd_vgaaddr - vgabase + off) >> PGSHIFT);
341
342 /*
343 * frame buffer
344 */
345 if (off >= linbase && off < (linbase + gi->gd_fbsize))
346 return(((paddr_t)gi->gd_fbaddr - linbase + off) >> PGSHIFT);
347 return(-1);
348 }
349
350 int
351 grfon(dev)
352 dev_t dev;
353 {
354 struct grf_softc *gp;
355
356 gp = grfsp[GRFUNIT(dev)];
357
358 if (gp->g_flags & GF_GRFON)
359 return(0);
360
361 gp->g_flags |= GF_GRFON;
362 if (gp->g_itedev != NODEV)
363 ite_off(gp->g_itedev, 3);
364
365 return(gp->g_mode(gp, (dev & GRFOVDEV) ? GM_GRFOVON : GM_GRFON,
366 NULL, 0, 0));
367 }
368
369 int
370 grfoff(dev)
371 dev_t dev;
372 {
373 struct grf_softc *gp;
374 int error;
375
376 gp = grfsp[GRFUNIT(dev)];
377
378 if ((gp->g_flags & GF_GRFON) == 0)
379 return(0);
380
381 gp->g_flags &= ~GF_GRFON;
382 error = gp->g_mode(gp, (dev & GRFOVDEV) ? GM_GRFOVOFF : GM_GRFOFF,
383 NULL, 0, 0);
384
385 /*
386 * Closely tied together no X's
387 */
388 if (gp->g_itedev != NODEV)
389 ite_on(gp->g_itedev, 2);
390
391 return(error);
392 }
393
394 int
395 grfsinfo(dev, dyninfo)
396 dev_t dev;
397 struct grfdyninfo *dyninfo;
398 {
399 struct grf_softc *gp;
400 int error;
401
402 gp = grfsp[GRFUNIT(dev)];
403 error = gp->g_mode(gp, GM_GRFCONFIG, dyninfo, 0, 0);
404
405 /*
406 * Closely tied together no X's
407 */
408 if (gp->g_itedev != NODEV)
409 ite_reinit(gp->g_itedev);
410 return(error);
411 }
412
413 /*
414 * Get the grf-info in sync with underlying view.
415 */
416 void
417 grf_viewsync(gp)
418 struct grf_softc *gp;
419 {
420 struct view_size vs;
421 bmap_t bm;
422 struct grfinfo *gi;
423 extern const struct cdevsw view_cdevsw;
424
425 gi = &gp->g_display;
426
427 (*view_cdevsw.d_ioctl)(gp->g_viewdev, VIOCGBMAP, (void *)&bm,
428 0, NOLWP);
429
430 gp->g_data = (void *) 0xDeadBeaf; /* not particularly clean.. */
431
432 gi->gd_fbaddr = bm.hw_address;
433 gi->gd_fbsize = bm.phys_mappable;
434 gi->gd_linbase = bm.lin_base;
435 gi->gd_regaddr = bm.hw_regs;
436 gi->gd_regsize = bm.reg_size;
437 gi->gd_vgaaddr = bm.vga_address;
438 gi->gd_vgasize = bm.vga_mappable;
439 gi->gd_vgabase = bm.vga_base;
440
441 if((*view_cdevsw.d_ioctl)(gp->g_viewdev, VIOCGSIZE, (void *)&vs, 0,
442 NOLWP)) {
443 /*
444 * fill in some default values...
445 * XXX: Should _never_ happen
446 */
447 vs.width = 640;
448 vs.height = 400;
449 vs.depth = 1;
450 }
451 gi->gd_colors = 1 << vs.depth;
452 gi->gd_planes = vs.depth;
453
454 gi->gd_fbwidth = vs.width;
455 gi->gd_fbheight = vs.height;
456 gi->gd_dyn.gdi_fbx = 0;
457 gi->gd_dyn.gdi_fby = 0;
458 gi->gd_dyn.gdi_dwidth = vs.width;
459 gi->gd_dyn.gdi_dheight = vs.height;
460 gi->gd_dyn.gdi_dx = 0;
461 gi->gd_dyn.gdi_dy = 0;
462 }
463
464 /*
465 * Change the mode of the display.
466 * Right now all we can do is grfon/grfoff.
467 * Return a UNIX error number or 0 for success.
468 */
469 /*ARGSUSED*/
470 int
471 grf_mode(gp, cmd, arg, a2, a3)
472 struct grf_softc *gp;
473 int cmd, a2, a3;
474 void *arg;
475 {
476 extern const struct cdevsw view_cdevsw;
477
478 switch (cmd) {
479 case GM_GRFON:
480 /*
481 * Get in sync with view, ite might have changed it.
482 */
483 grf_viewsync(gp);
484 (*view_cdevsw.d_ioctl)(gp->g_viewdev, VIOCDISPLAY,
485 NULL, 0, NOLWP);
486 return(0);
487 case GM_GRFOFF:
488 (*view_cdevsw.d_ioctl)(gp->g_viewdev, VIOCREMOVE,
489 NULL, 0, NOLWP);
490 return(0);
491 case GM_GRFCONFIG:
492 default:
493 break;
494 }
495 return(EPASSTHROUGH);
496 }
497 #endif /* NGRF > 0 */
498