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