1 /* $NetBSD: grf.c,v 1.34 2004/03/25 10:17:19 leo 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.34 2004/03/25 10:17:19 leo 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, p) 204 dev_t dev; 205 int flags, devtype; 206 struct proc *p; 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, p) 230 dev_t dev; 231 int flags; 232 int mode; 233 struct proc *p; 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, p) 246 dev_t dev; 247 u_long cmd; 248 int flag; 249 caddr_t data; 250 struct proc *p; 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((caddr_t)&gp->g_display, data, sizeof(struct grfinfo)-4); 263 break; 264 case GRFIOCGINFO: 265 bcopy((caddr_t)&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 p)); 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, (caddr_t)&bm, 428 0, NOPROC); 429 430 gp->g_data = (caddr_t) 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, (caddr_t)&vs, 0, 442 NOPROC)) { 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, NOPROC); 486 return(0); 487 case GM_GRFOFF: 488 (*view_cdevsw.d_ioctl)(gp->g_viewdev, VIOCREMOVE, 489 NULL, 0, NOPROC); 490 return(0); 491 case GM_GRFCONFIG: 492 default: 493 break; 494 } 495 return(EPASSTHROUGH); 496 } 497 #endif /* NGRF > 0 */ 498