grf.c revision 1.32
1/* $NetBSD: grf.c,v 1.32 1996/12/23 09:10:01 veego 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 <vm/vm.h> 62#include <vm/vm_kern.h> 63#include <vm/vm_page.h> 64#include <vm/vm_pager.h> 65#include <machine/cpu.h> 66#include <machine/fbio.h> 67#include <amiga/amiga/color.h> /* DEBUG */ 68#include <amiga/amiga/device.h> 69#include <amiga/dev/grfioctl.h> 70#include <amiga/dev/grfvar.h> 71#include <amiga/dev/itevar.h> 72#include <amiga/dev/viewioctl.h> 73 74#include <sys/conf.h> 75#include <machine/conf.h> 76 77#include "view.h" 78#include "grf.h" 79 80#if NGRF > 0 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 88int grfon __P((dev_t)); 89int grfoff __P((dev_t)); 90int grfsinfo __P((dev_t, struct grfdyninfo *)); 91#ifdef BANKEDDEVPAGER 92int grfbanked_get __P((dev_t, off_t, int)); 93int grfbanked_cur __P((dev_t)); 94int grfbanked_set __P((dev_t, int)); 95#endif 96 97void grfattach __P((struct device *, struct device *, void *)); 98int grfmatch __P((struct device *, struct cfdata *, void *)); 99int grfprint __P((void *, const char *)); 100/* 101 * pointers to grf drivers device structs 102 */ 103struct grf_softc *grfsp[NGRF]; 104 105struct cfattach grf_ca = { 106 sizeof(struct device), grfmatch, grfattach 107}; 108 109struct cfdriver grf_cd = { 110 NULL, "grf", DV_DULL, NULL, 0 111}; 112 113/* 114 * only used in console init. 115 */ 116static struct cfdata *cfdata; 117 118/* 119 * match if the unit of grf matches its perspective 120 * low level board driver. 121 */ 122int 123grfmatch(pdp, cfp, auxp) 124 struct device *pdp; 125 struct cfdata *cfp; 126 void *auxp; 127{ 128 129 if (cfp->cf_unit != ((struct grf_softc *)pdp)->g_unit) 130 return(0); 131 cfdata = cfp; 132 return(1); 133} 134 135/* 136 * attach.. plug pointer in and print some info. 137 * then try and attach an ite to us. note: dp is NULL 138 * durring console init. 139 */ 140void 141grfattach(pdp, dp, auxp) 142 struct device *pdp, *dp; 143 void *auxp; 144{ 145 struct grf_softc *gp; 146 int maj; 147 148 gp = (struct grf_softc *)pdp; 149 grfsp[gp->g_unit] = (struct grf_softc *)pdp; 150 151 /* 152 * find our major device number 153 */ 154 for(maj = 0; maj < nchrdev; maj++) 155 if (cdevsw[maj].d_open == grfopen) 156 break; 157 158 gp->g_grfdev = makedev(maj, gp->g_unit); 159 if (dp != NULL) { 160 printf(": width %d height %d", gp->g_display.gd_dwidth, 161 gp->g_display.gd_dheight); 162 if (gp->g_display.gd_colors == 2) 163 printf(" monochrome\n"); 164 else 165 printf(" colors %d\n", gp->g_display.gd_colors); 166 } 167 168 /* 169 * try and attach an ite 170 */ 171 amiga_config_found(cfdata, dp, gp, grfprint); 172} 173 174int 175grfprint(auxp, pnp) 176 void *auxp; 177 const char *pnp; 178{ 179 if (pnp) 180 printf("ite at %s", pnp); 181 return(UNCONF); 182} 183 184/*ARGSUSED*/ 185int 186grfopen(dev, flags, devtype, p) 187 dev_t dev; 188 int flags, devtype; 189 struct proc *p; 190{ 191 struct grf_softc *gp; 192 193 if (GRFUNIT(dev) >= NGRF || (gp = grfsp[GRFUNIT(dev)]) == NULL) 194 return(ENXIO); 195 196 if ((gp->g_flags & GF_ALIVE) == 0) 197 return(ENXIO); 198 199 if ((gp->g_flags & (GF_OPEN|GF_EXCLUDE)) == (GF_OPEN|GF_EXCLUDE)) 200 return(EBUSY); 201 202 return(0); 203} 204 205/*ARGSUSED*/ 206int 207grfclose(dev, flags, mode, p) 208 dev_t dev; 209 int flags; 210 int mode; 211 struct proc *p; 212{ 213 struct grf_softc *gp; 214 215 gp = grfsp[GRFUNIT(dev)]; 216 (void)grfoff(dev); 217 gp->g_flags &= GF_ALIVE; 218 return(0); 219} 220 221/*ARGSUSED*/ 222int 223grfioctl(dev, cmd, data, flag, p) 224 dev_t dev; 225 u_long cmd; 226 caddr_t data; 227 int flag; 228 struct proc *p; 229{ 230 struct grf_softc *gp; 231 int error; 232 233 gp = grfsp[GRFUNIT(dev)]; 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(dev); 246 break; 247 case GRFIOCOFF: 248 error = grfoff(dev); 249 break; 250 case GRFIOCSINFO: 251 error = grfsinfo(dev, (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 GRFIOCBLANK: /* blank ioctl, IOCON/OFF will turn ite on */ 276 case GRFTOGGLE: /* Toggles between Cirrus boards and native ECS on 277 Amiga. 15/11/94 ill */ 278 /* 279 * We need the minor dev number to get the overlay/image 280 * information for grf_ul. 281 */ 282 return(gp->g_mode(gp, GM_GRFIOCTL, data, cmd, dev)); 283 284 case FBIOSVIDEO: 285 return(gp->g_mode(gp, GM_GRFIOCTL, data, GRFIOCBLANK, dev)); 286 287 default: 288#if NVIEW > 0 289 /* 290 * check to see whether it's a command recognized by the 291 * view code if the unit is 0 292 * XXX 293 */ 294 if (GRFUNIT(dev) == 0) 295 return(viewioctl(dev, cmd, data, flag, p)); 296#endif 297 error = EINVAL; 298 break; 299 300 } 301 return(error); 302} 303 304/*ARGSUSED*/ 305int 306grfpoll(dev, events, p) 307 dev_t dev; 308 int events; 309 struct proc *p; 310{ 311 return(events & (POLLOUT | POLLWRNORM)); 312} 313 314/* 315 * map the contents of a graphics display card into process' 316 * memory space. 317 */ 318int 319grfmmap(dev, off, prot) 320 dev_t dev; 321 int off, prot; 322{ 323 struct grf_softc *gp; 324 struct grfinfo *gi; 325 326 gp = grfsp[GRFUNIT(dev)]; 327 gi = &gp->g_display; 328 329 /* 330 * control registers 331 */ 332 if (off >= 0 && off < gi->gd_regsize) 333 return(((u_int)gi->gd_regaddr + off) >> PGSHIFT); 334 335 /* 336 * frame buffer 337 */ 338 if (off >= gi->gd_regsize && off < gi->gd_regsize+gi->gd_fbsize) { 339 off -= gi->gd_regsize; 340#ifdef BANKEDDEVPAGER 341 if (gi->gd_bank_size) 342 off %= gi->gd_bank_size; 343#endif 344 return(((u_int)gi->gd_fbaddr + off) >> PGSHIFT); 345 } 346 /* bogus */ 347 return(-1); 348} 349 350int 351grfon(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 369int 370grfoff(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 394int 395grfsinfo(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#ifdef BANKEDDEVPAGER 414 415int 416grfbanked_get (dev, off, prot) 417 dev_t dev; 418 off_t off; 419 int prot; 420{ 421 struct grf_softc *gp; 422 struct grfinfo *gi; 423 int error, bank; 424 425 gp = grfsp[GRFUNIT(dev)]; 426 gi = &gp->g_display; 427 428 off -= gi->gd_regsize; 429 if (off < 0 || off >= gi->gd_fbsize) 430 return -1; 431 432 error = gp->g_mode(gp, GM_GRFGETBANK, &bank, off, prot); 433 return error ? -1 : bank; 434} 435 436int 437grfbanked_cur (dev) 438 dev_t dev; 439{ 440 struct grf_softc *gp; 441 int error, bank; 442 443 gp = grfsp[GRFUNIT(dev)]; 444 445 error = gp->g_mode(gp, GM_GRFGETCURBANK, &bank, 0, 0); 446 return(error ? -1 : bank); 447} 448 449int 450grfbanked_set (dev, bank) 451 dev_t dev; 452 int bank; 453{ 454 struct grf_softc *gp; 455 456 gp = grfsp[GRFUNIT(dev)]; 457 return(gp->g_mode(gp, GM_GRFSETBANK, &bank, 0, 0) ? -1 : 0); 458} 459 460#endif /* BANKEDDEVPAGER */ 461#endif /* NGRF > 0 */ 462