grf.c revision 1.31 1 /* $NetBSD: grf.c,v 1.31 2002/10/23 09:10:51 jdolecek 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
63 #include <machine/cpu.h>
64
65 #include <uvm/uvm_extern.h>
66
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 "grfcc.h"
76 #include "grfet.h"
77 #define NGRF (NGRFCC + NGRFET)
78
79 #if NGRF > 0
80
81 #include "ite.h"
82 #if NITE == 0
83 #define ite_on(u,f)
84 #define ite_off(u,f)
85 #define ite_reinit(d)
86 #endif
87
88 int grfon __P((dev_t));
89 int grfoff __P((dev_t));
90 int grfsinfo __P((dev_t, struct grfdyninfo *));
91
92 int grfbusprint __P((void *auxp, const char *));
93 int grfbusmatch __P((struct device *, struct cfdata *, void *));
94 void grfbusattach __P((struct device *, struct device *, void *));
95
96 /*
97 * pointers to grf drivers device structs
98 */
99 struct grf_softc *grfsp[NGRF]; /* XXX */
100
101 CFATTACH_DECL(grfbus, sizeof(struct device),
102 grfbusmatch, grfbusattach, NULL, NULL);
103
104 extern struct cfdriver grfbus_cd;
105
106 dev_type_open(grfopen);
107 dev_type_close(grfclose);
108 dev_type_ioctl(grfioctl);
109 dev_type_mmap(grfmmap);
110
111 const struct cdevsw grf_cdevsw = {
112 grfopen, grfclose, noread, nowrite, grfioctl,
113 nostop, notty, nopoll, grfmmap, nokqfilter,
114 };
115
116 /*
117 * only used in console init.
118 */
119 static struct cfdata *cfdata_gbus = NULL;
120
121 int
122 grfbusmatch(pdp, cfp, auxp)
123 struct device *pdp;
124 struct cfdata *cfp;
125 void *auxp;
126 {
127 if(strcmp(auxp, grfbus_cd.cd_name))
128 return(0);
129
130 if(atari_realconfig == 0)
131 cfdata_gbus = cfp;
132 return(1); /* Always there */
133 }
134
135 void
136 grfbusattach(pdp, dp, auxp)
137 struct device *pdp, *dp;
138 void *auxp;
139 {
140 grf_auxp_t grf_auxp;
141
142 grf_auxp.busprint = grfbusprint;
143 grf_auxp.from_bus_match = 1;
144
145 if(dp == NULL) /* Console init */
146 atari_config_found(cfdata_gbus, NULL, (void*)&grf_auxp, grfbusprint);
147 else {
148 printf("\n");
149 config_found(dp, (void*)&grf_auxp, grfbusprint);
150 }
151 }
152
153 int
154 grfbusprint(auxp, name)
155 void *auxp;
156 const char *name;
157 {
158 if(name == NULL)
159 return(UNCONF);
160 return(QUIET);
161 }
162
163 /*ARGSUSED*/
164 int
165 grfopen(dev, flags, devtype, p)
166 dev_t dev;
167 int flags, devtype;
168 struct proc *p;
169 {
170 struct grf_softc *gp;
171
172 if (GRFUNIT(dev) >= NGRF)
173 return(ENXIO);
174
175 gp = grfsp[GRFUNIT(dev)];
176 if (gp == NULL)
177 return(ENXIO);
178
179 if ((gp->g_flags & GF_ALIVE) == 0)
180 return(ENXIO);
181
182 if ((gp->g_flags & (GF_OPEN|GF_EXCLUDE)) == (GF_OPEN|GF_EXCLUDE))
183 return(EBUSY);
184 grf_viewsync(gp);
185
186 return(0);
187 }
188
189 /*ARGSUSED*/
190 int
191 grfclose(dev, flags, mode, p)
192 dev_t dev;
193 int flags;
194 int mode;
195 struct proc *p;
196 {
197 struct grf_softc *gp;
198
199 gp = grfsp[GRFUNIT(dev)];
200 (void)grfoff(dev);
201 gp->g_flags &= GF_ALIVE;
202 return(0);
203 }
204
205 /*ARGSUSED*/
206 int
207 grfioctl(dev, cmd, data, flag, p)
208 dev_t dev;
209 u_long cmd;
210 int flag;
211 caddr_t data;
212 struct proc *p;
213 {
214 struct grf_softc *gp;
215 int error;
216 extern const struct cdevsw view_cdevsw;
217
218 gp = grfsp[GRFUNIT(dev)];
219 error = 0;
220
221 switch (cmd) {
222 case OGRFIOCGINFO:
223 /* argl.. no bank-member.. */
224 bcopy((caddr_t)&gp->g_display, data, sizeof(struct grfinfo)-4);
225 break;
226 case GRFIOCGINFO:
227 bcopy((caddr_t)&gp->g_display, data, sizeof(struct grfinfo));
228 break;
229 case GRFIOCON:
230 error = grfon(dev);
231 break;
232 case GRFIOCOFF:
233 error = grfoff(dev);
234 break;
235 case GRFIOCSINFO:
236 error = grfsinfo(dev, (struct grfdyninfo *) data);
237 break;
238 case GRFGETVMODE:
239 return(gp->g_mode(gp, GM_GRFGETVMODE, data, 0, 0));
240 case GRFSETVMODE:
241 error = gp->g_mode(gp, GM_GRFSETVMODE, data, 0, 0);
242 if (error == 0 && gp->g_itedev)
243 ite_reinit(gp->g_itedev);
244 break;
245 case GRFGETNUMVM:
246 return(gp->g_mode(gp, GM_GRFGETNUMVM, data, 0, 0));
247 /*
248 * these are all hardware dependant, and have to be resolved
249 * in the respective driver.
250 */
251 case GRFIOCPUTCMAP:
252 case GRFIOCGETCMAP:
253 case GRFIOCSSPRITEPOS:
254 case GRFIOCGSPRITEPOS:
255 case GRFIOCSSPRITEINF:
256 case GRFIOCGSPRITEINF:
257 case GRFIOCGSPRITEMAX:
258 default:
259 /*
260 * check to see whether it's a command recognized by the
261 * view code.
262 */
263 return((*view_cdevsw.d_ioctl)(gp->g_viewdev, cmd, data, flag,
264 p));
265 error = EINVAL;
266 break;
267
268 }
269 return(error);
270 }
271
272 /*
273 * map the contents of a graphics display card into process'
274 * memory space.
275 */
276 paddr_t
277 grfmmap(dev, off, prot)
278 dev_t dev;
279 off_t off;
280 int prot;
281 {
282 struct grf_softc *gp;
283 struct grfinfo *gi;
284 u_int vgabase, linbase;
285
286 gp = grfsp[GRFUNIT(dev)];
287 gi = &gp->g_display;
288
289 vgabase = gi->gd_vgabase;
290 linbase = gi->gd_linbase;
291
292 /*
293 * control registers
294 */
295 if (off >= 0 && off < gi->gd_regsize)
296 return(((paddr_t)gi->gd_regaddr + off) >> PGSHIFT);
297
298 /*
299 * VGA memory
300 */
301 if (off >= vgabase && off < (vgabase + gi->gd_vgasize))
302 return(((paddr_t)gi->gd_vgaaddr - vgabase + off) >> PGSHIFT);
303
304 /*
305 * frame buffer
306 */
307 if (off >= linbase && off < (linbase + gi->gd_fbsize))
308 return(((paddr_t)gi->gd_fbaddr - linbase + off) >> PGSHIFT);
309 return(-1);
310 }
311
312 int
313 grfon(dev)
314 dev_t dev;
315 {
316 struct grf_softc *gp;
317
318 gp = grfsp[GRFUNIT(dev)];
319
320 if (gp->g_flags & GF_GRFON)
321 return(0);
322
323 gp->g_flags |= GF_GRFON;
324 if (gp->g_itedev != NODEV)
325 ite_off(gp->g_itedev, 3);
326
327 return(gp->g_mode(gp, (dev & GRFOVDEV) ? GM_GRFOVON : GM_GRFON,
328 NULL, 0, 0));
329 }
330
331 int
332 grfoff(dev)
333 dev_t dev;
334 {
335 struct grf_softc *gp;
336 int error;
337
338 gp = grfsp[GRFUNIT(dev)];
339
340 if ((gp->g_flags & GF_GRFON) == 0)
341 return(0);
342
343 gp->g_flags &= ~GF_GRFON;
344 error = gp->g_mode(gp, (dev & GRFOVDEV) ? GM_GRFOVOFF : GM_GRFOFF,
345 NULL, 0, 0);
346
347 /*
348 * Closely tied together no X's
349 */
350 if (gp->g_itedev != NODEV)
351 ite_on(gp->g_itedev, 2);
352
353 return(error);
354 }
355
356 int
357 grfsinfo(dev, dyninfo)
358 dev_t dev;
359 struct grfdyninfo *dyninfo;
360 {
361 struct grf_softc *gp;
362 int error;
363
364 gp = grfsp[GRFUNIT(dev)];
365 error = gp->g_mode(gp, GM_GRFCONFIG, dyninfo, 0, 0);
366
367 /*
368 * Closely tied together no X's
369 */
370 if (gp->g_itedev != NODEV)
371 ite_reinit(gp->g_itedev);
372 return(error);
373 }
374
375 /*
376 * Get the grf-info in sync with underlying view.
377 */
378 void
379 grf_viewsync(gp)
380 struct grf_softc *gp;
381 {
382 struct view_size vs;
383 bmap_t bm;
384 struct grfinfo *gi;
385 extern const struct cdevsw view_cdevsw;
386
387 gi = &gp->g_display;
388
389 (*view_cdevsw.d_ioctl)(gp->g_viewdev, VIOCGBMAP, (caddr_t)&bm,
390 0, NOPROC);
391
392 gp->g_data = (caddr_t) 0xDeadBeaf; /* not particularly clean.. */
393
394 gi->gd_fbaddr = bm.hw_address;
395 gi->gd_fbsize = bm.phys_mappable;
396 gi->gd_linbase = bm.lin_base;
397 gi->gd_regaddr = bm.hw_regs;
398 gi->gd_regsize = bm.reg_size;
399 gi->gd_vgaaddr = bm.vga_address;
400 gi->gd_vgasize = bm.vga_mappable;
401 gi->gd_vgabase = bm.vga_base;
402
403 if((*view_cdevsw.d_ioctl)(gp->g_viewdev, VIOCGSIZE, (caddr_t)&vs, 0,
404 NOPROC)) {
405 /*
406 * fill in some default values...
407 * XXX: Should _never_ happen
408 */
409 vs.width = 640;
410 vs.height = 400;
411 vs.depth = 1;
412 }
413 gi->gd_colors = 1 << vs.depth;
414 gi->gd_planes = vs.depth;
415
416 gi->gd_fbwidth = vs.width;
417 gi->gd_fbheight = vs.height;
418 gi->gd_dyn.gdi_fbx = 0;
419 gi->gd_dyn.gdi_fby = 0;
420 gi->gd_dyn.gdi_dwidth = vs.width;
421 gi->gd_dyn.gdi_dheight = vs.height;
422 gi->gd_dyn.gdi_dx = 0;
423 gi->gd_dyn.gdi_dy = 0;
424 }
425
426 /*
427 * Change the mode of the display.
428 * Right now all we can do is grfon/grfoff.
429 * Return a UNIX error number or 0 for success.
430 */
431 /*ARGSUSED*/
432 int
433 grf_mode(gp, cmd, arg, a2, a3)
434 struct grf_softc *gp;
435 int cmd, a2, a3;
436 void *arg;
437 {
438 extern const struct cdevsw view_cdevsw;
439
440 switch (cmd) {
441 case GM_GRFON:
442 /*
443 * Get in sync with view, ite might have changed it.
444 */
445 grf_viewsync(gp);
446 (*view_cdevsw.d_ioctl)(gp->g_viewdev, VIOCDISPLAY,
447 NULL, 0, NOPROC);
448 return(0);
449 case GM_GRFOFF:
450 (*view_cdevsw.d_ioctl)(gp->g_viewdev, VIOCREMOVE,
451 NULL, 0, NOPROC);
452 return(0);
453 case GM_GRFCONFIG:
454 default:
455 break;
456 }
457 return(EPASSTHROUGH);
458 }
459 #endif /* NGRF > 0 */
460