1 /* $NetBSD: grf.c,v 1.40 2009/03/18 17:06:43 cegger 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.40 2009/03/18 17:06:43 cegger 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(dev_t); 127 int grfoff(dev_t); 128 int grfsinfo(dev_t, struct grfdyninfo *); 129 130 int grfbusprint(void *auxp, const char *); 131 int grfbusmatch(struct device *, struct cfdata *, void *); 132 void grfbusattach(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(struct device *pdp, struct cfdata *cfp, void *auxp) 161 { 162 if(strcmp(auxp, grfbus_cd.cd_name)) 163 return(0); 164 165 if(atari_realconfig == 0) 166 cfdata_gbus = cfp; 167 return(1); /* Always there */ 168 } 169 170 void 171 grfbusattach(struct device *pdp, struct device *dp, void *auxp) 172 { 173 grf_auxp_t grf_auxp; 174 175 grf_auxp.busprint = grfbusprint; 176 grf_auxp.from_bus_match = 1; 177 178 if(dp == NULL) /* Console init */ 179 atari_config_found(cfdata_gbus, NULL, (void*)&grf_auxp, grfbusprint); 180 else { 181 printf("\n"); 182 config_found(dp, (void*)&grf_auxp, grfbusprint); 183 } 184 } 185 186 int 187 grfbusprint(void *auxp, const char *name) 188 { 189 if(name == NULL) 190 return(UNCONF); 191 return(QUIET); 192 } 193 194 /*ARGSUSED*/ 195 int 196 grfopen(dev_t dev, int flags, int devtype, struct lwp *l) 197 { 198 struct grf_softc *gp; 199 200 if (GRFUNIT(dev) >= NGRF) 201 return(ENXIO); 202 203 gp = grfsp[GRFUNIT(dev)]; 204 if (gp == NULL) 205 return(ENXIO); 206 207 if ((gp->g_flags & GF_ALIVE) == 0) 208 return(ENXIO); 209 210 if ((gp->g_flags & (GF_OPEN|GF_EXCLUDE)) == (GF_OPEN|GF_EXCLUDE)) 211 return(EBUSY); 212 grf_viewsync(gp); 213 214 return(0); 215 } 216 217 /*ARGSUSED*/ 218 int 219 grfclose(dev_t dev, int flags, int mode, struct lwp *l) 220 { 221 struct grf_softc *gp; 222 223 gp = grfsp[GRFUNIT(dev)]; 224 (void)grfoff(dev); 225 gp->g_flags &= GF_ALIVE; 226 return(0); 227 } 228 229 /*ARGSUSED*/ 230 int 231 grfioctl(dev_t dev, u_long cmd, void * data, int flag, struct lwp *l) 232 { 233 struct grf_softc *gp; 234 int error; 235 extern const struct cdevsw view_cdevsw; 236 237 gp = grfsp[GRFUNIT(dev)]; 238 error = 0; 239 240 switch (cmd) { 241 case OGRFIOCGINFO: 242 /* argl.. no bank-member.. */ 243 memcpy( data, (void *)&gp->g_display, sizeof(struct grfinfo)-4); 244 break; 245 case GRFIOCGINFO: 246 memcpy( data, (void *)&gp->g_display, sizeof(struct grfinfo)); 247 break; 248 case GRFIOCON: 249 error = grfon(dev); 250 break; 251 case GRFIOCOFF: 252 error = grfoff(dev); 253 break; 254 case GRFIOCSINFO: 255 error = grfsinfo(dev, (struct grfdyninfo *) data); 256 break; 257 case GRFGETVMODE: 258 return(gp->g_mode(gp, GM_GRFGETVMODE, data, 0, 0)); 259 case GRFSETVMODE: 260 error = gp->g_mode(gp, GM_GRFSETVMODE, data, 0, 0); 261 if (error == 0 && gp->g_itedev) 262 ite_reinit(gp->g_itedev); 263 break; 264 case GRFGETNUMVM: 265 return(gp->g_mode(gp, GM_GRFGETNUMVM, data, 0, 0)); 266 /* 267 * these are all hardware dependant, and have to be resolved 268 * in the respective driver. 269 */ 270 case GRFIOCPUTCMAP: 271 case GRFIOCGETCMAP: 272 case GRFIOCSSPRITEPOS: 273 case GRFIOCGSPRITEPOS: 274 case GRFIOCSSPRITEINF: 275 case GRFIOCGSPRITEINF: 276 case GRFIOCGSPRITEMAX: 277 default: 278 /* 279 * check to see whether it's a command recognized by the 280 * view code. 281 */ 282 return((*view_cdevsw.d_ioctl)(gp->g_viewdev, cmd, data, flag, 283 l)); 284 error = EINVAL; 285 break; 286 287 } 288 return(error); 289 } 290 291 /* 292 * map the contents of a graphics display card into process' 293 * memory space. 294 */ 295 paddr_t 296 grfmmap(dev_t dev, off_t off, int prot) 297 { 298 struct grf_softc *gp; 299 struct grfinfo *gi; 300 u_int vgabase, linbase; 301 302 gp = grfsp[GRFUNIT(dev)]; 303 gi = &gp->g_display; 304 305 vgabase = gi->gd_vgabase; 306 linbase = gi->gd_linbase; 307 308 /* 309 * control registers 310 */ 311 if (off >= 0 && off < gi->gd_regsize) 312 return(((paddr_t)gi->gd_regaddr + off) >> PGSHIFT); 313 314 /* 315 * VGA memory 316 */ 317 if (off >= vgabase && off < (vgabase + gi->gd_vgasize)) 318 return(((paddr_t)gi->gd_vgaaddr - vgabase + off) >> PGSHIFT); 319 320 /* 321 * frame buffer 322 */ 323 if (off >= linbase && off < (linbase + gi->gd_fbsize)) 324 return(((paddr_t)gi->gd_fbaddr - linbase + off) >> PGSHIFT); 325 return(-1); 326 } 327 328 int 329 grfon(dev_t dev) 330 { 331 struct grf_softc *gp; 332 333 gp = grfsp[GRFUNIT(dev)]; 334 335 if (gp->g_flags & GF_GRFON) 336 return(0); 337 338 gp->g_flags |= GF_GRFON; 339 if (gp->g_itedev != NODEV) 340 ite_off(gp->g_itedev, 3); 341 342 return(gp->g_mode(gp, (dev & GRFOVDEV) ? GM_GRFOVON : GM_GRFON, 343 NULL, 0, 0)); 344 } 345 346 int 347 grfoff(dev_t dev) 348 { 349 struct grf_softc *gp; 350 int error; 351 352 gp = grfsp[GRFUNIT(dev)]; 353 354 if ((gp->g_flags & GF_GRFON) == 0) 355 return(0); 356 357 gp->g_flags &= ~GF_GRFON; 358 error = gp->g_mode(gp, (dev & GRFOVDEV) ? GM_GRFOVOFF : GM_GRFOFF, 359 NULL, 0, 0); 360 361 /* 362 * Closely tied together no X's 363 */ 364 if (gp->g_itedev != NODEV) 365 ite_on(gp->g_itedev, 2); 366 367 return(error); 368 } 369 370 int 371 grfsinfo(dev_t dev, struct grfdyninfo *dyninfo) 372 { 373 struct grf_softc *gp; 374 int error; 375 376 gp = grfsp[GRFUNIT(dev)]; 377 error = gp->g_mode(gp, GM_GRFCONFIG, dyninfo, 0, 0); 378 379 /* 380 * Closely tied together no X's 381 */ 382 if (gp->g_itedev != NODEV) 383 ite_reinit(gp->g_itedev); 384 return(error); 385 } 386 387 /* 388 * Get the grf-info in sync with underlying view. 389 */ 390 void 391 grf_viewsync(struct grf_softc *gp) 392 { 393 struct view_size vs; 394 bmap_t bm; 395 struct grfinfo *gi; 396 extern const struct cdevsw view_cdevsw; 397 398 gi = &gp->g_display; 399 400 (*view_cdevsw.d_ioctl)(gp->g_viewdev, VIOCGBMAP, (void *)&bm, 401 0, NOLWP); 402 403 gp->g_data = (void *) 0xDeadBeaf; /* not particularly clean.. */ 404 405 gi->gd_fbaddr = bm.hw_address; 406 gi->gd_fbsize = bm.phys_mappable; 407 gi->gd_linbase = bm.lin_base; 408 gi->gd_regaddr = bm.hw_regs; 409 gi->gd_regsize = bm.reg_size; 410 gi->gd_vgaaddr = bm.vga_address; 411 gi->gd_vgasize = bm.vga_mappable; 412 gi->gd_vgabase = bm.vga_base; 413 414 if((*view_cdevsw.d_ioctl)(gp->g_viewdev, VIOCGSIZE, (void *)&vs, 0, 415 NOLWP)) { 416 /* 417 * fill in some default values... 418 * XXX: Should _never_ happen 419 */ 420 vs.width = 640; 421 vs.height = 400; 422 vs.depth = 1; 423 } 424 gi->gd_colors = 1 << vs.depth; 425 gi->gd_planes = vs.depth; 426 427 gi->gd_fbwidth = vs.width; 428 gi->gd_fbheight = vs.height; 429 gi->gd_dyn.gdi_fbx = 0; 430 gi->gd_dyn.gdi_fby = 0; 431 gi->gd_dyn.gdi_dwidth = vs.width; 432 gi->gd_dyn.gdi_dheight = vs.height; 433 gi->gd_dyn.gdi_dx = 0; 434 gi->gd_dyn.gdi_dy = 0; 435 } 436 437 /* 438 * Change the mode of the display. 439 * Right now all we can do is grfon/grfoff. 440 * Return a UNIX error number or 0 for success. 441 */ 442 /*ARGSUSED*/ 443 int 444 grf_mode(struct grf_softc *gp, int cmd, void *arg, int a2, int a3) 445 { 446 extern const struct cdevsw view_cdevsw; 447 448 switch (cmd) { 449 case GM_GRFON: 450 /* 451 * Get in sync with view, ite might have changed it. 452 */ 453 grf_viewsync(gp); 454 (*view_cdevsw.d_ioctl)(gp->g_viewdev, VIOCDISPLAY, 455 NULL, 0, NOLWP); 456 return(0); 457 case GM_GRFOFF: 458 (*view_cdevsw.d_ioctl)(gp->g_viewdev, VIOCREMOVE, 459 NULL, 0, NOLWP); 460 return(0); 461 case GM_GRFCONFIG: 462 default: 463 break; 464 } 465 return(EPASSTHROUGH); 466 } 467 #endif /* NGRF > 0 */ 468