1 /* $NetBSD: grf.c,v 1.16 1994/12/01 17:24:58 chopps 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/conf.h> 58 #include <sys/systm.h> 59 #include <sys/vnode.h> 60 #include <sys/mman.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 <amiga/amiga/color.h> /* DEBUG */ 67 #include <amiga/amiga/device.h> 68 #include <amiga/dev/grfioctl.h> 69 #include <amiga/dev/grfvar.h> 70 #include <amiga/dev/itevar.h> 71 72 #include "grf.h" 73 #if NGRF > 0 74 75 #include "ite.h" 76 #if NITE == 0 77 #define ite_on(u,f) 78 #define ite_off(u,f) 79 #define ite_reinit(d) 80 #endif 81 82 int grfopen __P((dev_t, int, int, struct proc *)); 83 int grfclose __P((dev_t, int)); 84 int grfioctl __P((dev_t, u_long, caddr_t, int, struct proc *)); 85 int grfselect __P((dev_t, int)); 86 int grfmap __P((dev_t, int, int)); 87 88 int grfon __P((dev_t)); 89 int grfoff __P((dev_t)); 90 int grfsinfo __P((dev_t, struct grfdyninfo *)); 91 #ifdef BANKEDDEVPAGER 92 int grfbanked_get __P((dev_t, off_t, int)); 93 int grfbanked_cur __P((dev_t)); 94 int grfbanked_set __P((dev_t, int)); 95 #endif 96 97 void grfattach __P((struct device *, struct device *, void *)); 98 int grfmatch __P((struct device *, struct cfdata *, void *)); 99 int grfprint __P((void *, char *)); 100 /* 101 * pointers to grf drivers device structs 102 */ 103 struct grf_softc *grfsp[NGRF]; 104 105 106 struct cfdriver grfcd = { 107 NULL, "grf", (cfmatch_t)grfmatch, grfattach, DV_DULL, 108 sizeof(struct device), NULL, 0 }; 109 110 /* 111 * only used in console init. 112 */ 113 static struct cfdata *cfdata; 114 115 /* 116 * match if the unit of grf matches its perspective 117 * low level board driver. 118 */ 119 int 120 grfmatch(pdp, cfp, auxp) 121 struct device *pdp; 122 struct cfdata *cfp; 123 void *auxp; 124 { 125 if (cfp->cf_unit != ((struct grf_softc *)pdp)->g_unit) 126 return(0); 127 cfdata = cfp; 128 return(1); 129 } 130 131 /* 132 * attach.. plug pointer in and print some info. 133 * then try and attach an ite to us. note: dp is NULL 134 * durring console init. 135 */ 136 void 137 grfattach(pdp, dp, auxp) 138 struct device *pdp, *dp; 139 void *auxp; 140 { 141 struct grf_softc *gp; 142 int maj; 143 144 gp = (struct grf_softc *)pdp; 145 grfsp[gp->g_unit] = (struct grf_softc *)pdp; 146 147 /* 148 * find our major device number 149 */ 150 for(maj = 0; maj < nchrdev; maj++) 151 if (cdevsw[maj].d_open == 152 (int (*)__P((dev_t,int,int,struct proc *,struct file*))) 153 grfopen) 154 break; 155 156 gp->g_grfdev = makedev(maj, gp->g_unit); 157 if (dp != NULL) { 158 printf(": width %d height %d", gp->g_display.gd_dwidth, 159 gp->g_display.gd_dheight); 160 if (gp->g_display.gd_colors == 2) 161 printf(" monochrome\n"); 162 else 163 printf(" colors %d\n", gp->g_display.gd_colors); 164 } 165 166 /* 167 * try and attach an ite 168 */ 169 amiga_config_found(cfdata, dp, gp, grfprint); 170 } 171 172 int 173 grfprint(auxp, pnp) 174 void *auxp; 175 char *pnp; 176 { 177 if (pnp) 178 printf("ite at %s", pnp); 179 return(UNCONF); 180 } 181 182 /*ARGSUSED*/ 183 int 184 grfopen(dev, flags, devtype, p) 185 dev_t dev; 186 int flags, devtype; 187 struct proc *p; 188 { 189 struct grf_softc *gp; 190 191 if (GRFUNIT(dev) >= NGRF) 192 return(ENXIO); 193 194 gp = grfsp[GRFUNIT(dev)]; 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*/ 206 int 207 grfclose(dev, flags) 208 dev_t dev; 209 int flags; 210 { 211 struct grf_softc *gp; 212 213 gp = grfsp[GRFUNIT(dev)]; 214 (void)grfoff(dev); 215 gp->g_flags &= GF_ALIVE; 216 return(0); 217 } 218 219 /*ARGSUSED*/ 220 int 221 grfioctl(dev, cmd, data, flag, p) 222 dev_t dev; 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 231 gp = grfsp[GRFUNIT(dev)]; 232 error = 0; 233 234 switch (cmd) { 235 case OGRFIOCGINFO: 236 /* argl.. no bank-member.. */ 237 bcopy((caddr_t)&gp->g_display, data, sizeof(struct grfinfo)-4); 238 break; 239 case GRFIOCGINFO: 240 bcopy((caddr_t)&gp->g_display, data, sizeof(struct grfinfo)); 241 break; 242 case GRFIOCON: 243 error = grfon(dev); 244 break; 245 case GRFIOCOFF: 246 error = grfoff(dev); 247 break; 248 case GRFIOCSINFO: 249 error = grfsinfo(dev, (struct grfdyninfo *) data); 250 break; 251 case GRFGETVMODE: 252 return(gp->g_mode(gp, GM_GRFGETVMODE, data)); 253 case GRFSETVMODE: 254 error = gp->g_mode(gp, GM_GRFSETVMODE, data); 255 if (error == 0 && gp->g_itedev) 256 ite_reinit(gp->g_itedev); 257 break; 258 case GRFGETNUMVM: 259 return(gp->g_mode(gp, GM_GRFGETNUMVM, data)); 260 /* 261 * these are all hardware dependant, and have to be resolved 262 * in the respective driver. 263 */ 264 case GRFIOCPUTCMAP: 265 case GRFIOCGETCMAP: 266 case GRFIOCSSPRITEPOS: 267 case GRFIOCGSPRITEPOS: 268 case GRFIOCSSPRITEINF: 269 case GRFIOCGSPRITEINF: 270 case GRFIOCGSPRITEMAX: 271 return(gp->g_mode(gp, GM_GRFIOCTL, cmd, data)); 272 default: 273 /* 274 * check to see whether it's a command recognized by the 275 * view code if the unit is 0 276 * XXX 277 */ 278 if (GRFUNIT(dev) == 0) 279 return(viewioctl(dev, cmd, data, flag, p)); 280 error = EINVAL; 281 break; 282 283 } 284 return(error); 285 } 286 287 /*ARGSUSED*/ 288 int 289 grfselect(dev, rw) 290 dev_t dev; 291 int rw; 292 { 293 if (rw == FREAD) 294 return(0); 295 return(1); 296 } 297 298 /* 299 * map the contents of a graphics display card into process' 300 * memory space. 301 */ 302 int 303 grfmap(dev, off, prot) 304 dev_t dev; 305 int off, prot; 306 { 307 struct grf_softc *gp; 308 struct grfinfo *gi; 309 310 gp = grfsp[GRFUNIT(dev)]; 311 gi = &gp->g_display; 312 313 /* 314 * control registers 315 */ 316 if (off >= 0 && off < gi->gd_regsize) 317 return(((u_int)gi->gd_regaddr + off) >> PGSHIFT); 318 319 /* 320 * frame buffer 321 */ 322 if (off >= gi->gd_regsize && off < gi->gd_regsize+gi->gd_fbsize) { 323 off -= gi->gd_regsize; 324 #ifdef BANKEDDEVPAGER 325 if (gi->gd_bank_size) 326 off %= gi->gd_bank_size; 327 #endif 328 return(((u_int)gi->gd_fbaddr + off) >> PGSHIFT); 329 } 330 /* bogus */ 331 return(-1); 332 } 333 334 int 335 grfon(dev) 336 dev_t dev; 337 { 338 struct grf_softc *gp; 339 340 gp = grfsp[GRFUNIT(dev)]; 341 342 if (gp->g_flags & GF_GRFON) 343 return(0); 344 345 gp->g_flags |= GF_GRFON; 346 if (gp->g_itedev != NODEV) 347 ite_off(gp->g_itedev, 3); 348 349 return(gp->g_mode(gp, (dev & GRFOVDEV) ? GM_GRFOVON : GM_GRFON)); 350 } 351 352 int 353 grfoff(dev) 354 dev_t dev; 355 { 356 struct grf_softc *gp; 357 int error; 358 359 gp = grfsp[GRFUNIT(dev)]; 360 361 if ((gp->g_flags & GF_GRFON) == 0) 362 return(0); 363 364 gp->g_flags &= ~GF_GRFON; 365 error = gp->g_mode(gp, (dev & GRFOVDEV) ? GM_GRFOVOFF : GM_GRFOFF); 366 367 /* 368 * Closely tied together no X's 369 */ 370 if (gp->g_itedev != NODEV) 371 ite_on(gp->g_itedev, 2); 372 373 return(error); 374 } 375 376 int 377 grfsinfo(dev, dyninfo) 378 dev_t dev; 379 struct grfdyninfo *dyninfo; 380 { 381 struct grf_softc *gp; 382 int error; 383 384 gp = grfsp[GRFUNIT(dev)]; 385 error = gp->g_mode(gp, GM_GRFCONFIG, dyninfo); 386 387 /* 388 * Closely tied together no X's 389 */ 390 if (gp->g_itedev != NODEV) 391 ite_reinit(gp->g_itedev); 392 return(error); 393 } 394 395 #ifdef BANKEDDEVPAGER 396 397 int 398 grfbanked_get (dev, off, prot) 399 dev_t dev; 400 off_t off; 401 int prot; 402 { 403 struct grf_softc *gp; 404 struct grfinfo *gi; 405 int error, bank; 406 407 gp = grfsp[GRFUNIT(dev)]; 408 gi = &gp->g_display; 409 410 off -= gi->gd_regsize; 411 if (off < 0 || off >= gi->gd_fbsize) 412 return -1; 413 414 error = gp->g_mode(gp, GM_GRFGETBANK, &bank, off, prot); 415 return error ? -1 : bank; 416 } 417 418 int 419 grfbanked_cur (dev) 420 dev_t dev; 421 { 422 struct grf_softc *gp; 423 int error, bank; 424 425 gp = grfsp[GRFUNIT(dev)]; 426 427 error = gp->g_mode(gp, GM_GRFGETCURBANK, &bank); 428 return(error ? -1 : bank); 429 } 430 431 int 432 grfbanked_set (dev, bank) 433 dev_t dev; 434 int bank; 435 { 436 struct grf_softc *gp; 437 438 gp = grfsp[GRFUNIT(dev)]; 439 return(gp->g_mode(gp, GM_GRFSETBANK, bank) ? -1 : 0); 440 } 441 442 #endif /* BANKEDDEVPAGER */ 443 #endif /* NGRF > 0 */ 444