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