1 /* $NetBSD: grf.c,v 1.53 2010/12/20 00:25:25 matt Exp $ */ 2 3 /* 4 * Copyright (c) 1990 The Regents of the University of California. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * the Systems Programming Group of the University of Utah Computer 9 * Science Department. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * from: Utah $Hdr: grf.c 1.31 91/01/21$ 36 * 37 * @(#)grf.c 7.8 (Berkeley) 5/7/91 38 */ 39 /* 40 * Copyright (c) 1988 University of Utah. 41 * 42 * This code is derived from software contributed to Berkeley by 43 * the Systems Programming Group of the University of Utah Computer 44 * Science Department. 45 * 46 * Redistribution and use in source and binary forms, with or without 47 * modification, are permitted provided that the following conditions 48 * are met: 49 * 1. Redistributions of source code must retain the above copyright 50 * notice, this list of conditions and the following disclaimer. 51 * 2. Redistributions in binary form must reproduce the above copyright 52 * notice, this list of conditions and the following disclaimer in the 53 * documentation and/or other materials provided with the distribution. 54 * 3. All advertising materials mentioning features or use of this software 55 * must display the following acknowledgement: 56 * This product includes software developed by the University of 57 * California, Berkeley and its contributors. 58 * 4. Neither the name of the University nor the names of its contributors 59 * may be used to endorse or promote products derived from this software 60 * without specific prior written permission. 61 * 62 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 63 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 64 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 65 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 66 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 67 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 68 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 69 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 70 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 71 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 72 * SUCH DAMAGE. 73 * 74 * from: Utah $Hdr: grf.c 1.31 91/01/21$ 75 * 76 * @(#)grf.c 7.8 (Berkeley) 5/7/91 77 */ 78 79 #include <sys/cdefs.h> 80 __KERNEL_RCSID(0, "$NetBSD: grf.c,v 1.53 2010/12/20 00:25:25 matt Exp $"); 81 82 /* 83 * Graphics display driver for the Amiga 84 * This is the hardware-independent portion of the driver. 85 * Hardware access is through the grf_softc->g_mode routine. 86 */ 87 88 #include <sys/param.h> 89 #include <sys/proc.h> 90 #include <sys/ioctl.h> 91 #include <sys/device.h> 92 #include <sys/file.h> 93 #include <sys/malloc.h> 94 #include <sys/systm.h> 95 #include <sys/vnode.h> 96 #include <sys/mman.h> 97 #include <machine/cpu.h> 98 #include <dev/sun/fbio.h> 99 #include <amiga/amiga/color.h> /* DEBUG */ 100 #include <amiga/amiga/device.h> 101 #include <amiga/dev/grfioctl.h> 102 #include <amiga/dev/grfvar.h> 103 #include <amiga/dev/itevar.h> 104 #include <amiga/dev/viewioctl.h> 105 106 #include <sys/conf.h> 107 108 #include "view.h" 109 #include "grf.h" 110 111 #if NGRF > 0 112 #include "ite.h" 113 #if NITE == 0 114 #define ite_on(u,f) 115 #define ite_off(u,f) 116 #define ite_reinit(d) 117 #endif 118 119 int grfon(dev_t); 120 int grfoff(dev_t); 121 int grfsinfo(dev_t, struct grfdyninfo *); 122 123 void grfattach(struct device *, struct device *, void *); 124 int grfmatch(struct device *, struct cfdata *, void *); 125 int grfprint(void *, const char *); 126 /* 127 * pointers to grf drivers device structs 128 */ 129 struct grf_softc *grfsp[NGRF]; 130 131 CFATTACH_DECL(grf, sizeof(struct device), 132 grfmatch, grfattach, NULL, NULL); 133 134 dev_type_open(grfopen); 135 dev_type_close(grfclose); 136 dev_type_ioctl(grfioctl); 137 dev_type_mmap(grfmmap); 138 139 const struct cdevsw grf_cdevsw = { 140 grfopen, grfclose, nullread, nullwrite, grfioctl, 141 nostop, notty, nopoll, grfmmap, nokqfilter, 142 }; 143 144 /* 145 * only used in console init. 146 */ 147 static struct cfdata *cfdata; 148 149 /* 150 * match if the unit of grf matches its perspective 151 * low level board driver. 152 */ 153 int 154 grfmatch(struct device *pdp, struct cfdata *cfp, void *auxp) 155 { 156 157 if (cfp->cf_unit != ((struct grf_softc *)pdp)->g_unit) 158 return(0); 159 cfdata = cfp; 160 return(1); 161 } 162 163 /* 164 * attach.. plug pointer in and print some info. 165 * then try and attach an ite to us. note: dp is NULL 166 * durring console init. 167 */ 168 void 169 grfattach(struct device *pdp, struct device *dp, void *auxp) 170 { 171 struct grf_softc *gp; 172 int maj; 173 174 gp = (struct grf_softc *)pdp; 175 grfsp[gp->g_unit] = (struct grf_softc *)pdp; 176 177 /* 178 * find our major device number 179 */ 180 maj = cdevsw_lookup_major(&grf_cdevsw); 181 182 gp->g_grfdev = makedev(maj, gp->g_unit); 183 if (dp != NULL) { 184 printf(": width %d height %d", gp->g_display.gd_dwidth, 185 gp->g_display.gd_dheight); 186 if (gp->g_display.gd_colors == 2) 187 printf(" monochrome\n"); 188 else 189 printf(" colors %d\n", gp->g_display.gd_colors); 190 } 191 192 /* 193 * try and attach an ite 194 */ 195 amiga_config_found(cfdata, dp, gp, grfprint); 196 } 197 198 int 199 grfprint(void *auxp, const char *pnp) 200 { 201 if (pnp) 202 aprint_normal("ite at %s", pnp); 203 return(UNCONF); 204 } 205 206 /*ARGSUSED*/ 207 int 208 grfopen(dev_t dev, int flags, int devtype, struct lwp *l) 209 { 210 struct grf_softc *gp; 211 212 if (GRFUNIT(dev) >= NGRF || (gp = grfsp[GRFUNIT(dev)]) == NULL) 213 return(ENXIO); 214 215 if ((gp->g_flags & GF_ALIVE) == 0) 216 return(ENXIO); 217 218 if ((gp->g_flags & (GF_OPEN|GF_EXCLUDE)) == (GF_OPEN|GF_EXCLUDE)) 219 return(EBUSY); 220 221 return(0); 222 } 223 224 /*ARGSUSED*/ 225 int 226 grfclose(dev_t dev, int flags, int mode, struct lwp *l) 227 { 228 struct grf_softc *gp; 229 230 gp = grfsp[GRFUNIT(dev)]; 231 (void)grfoff(dev); 232 gp->g_flags &= GF_ALIVE; 233 return(0); 234 } 235 236 /*ARGSUSED*/ 237 int 238 grfioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 239 { 240 struct grf_softc *gp; 241 int error; 242 243 gp = grfsp[GRFUNIT(dev)]; 244 error = 0; 245 246 switch (cmd) { 247 case OGRFIOCGINFO: 248 /* argl.. no bank-member.. */ 249 memcpy(data, (void *)&gp->g_display, sizeof(struct grfinfo)-4); 250 break; 251 case GRFIOCGINFO: 252 memcpy(data, (void *)&gp->g_display, sizeof(struct grfinfo)); 253 break; 254 case GRFIOCON: 255 error = grfon(dev); 256 break; 257 case GRFIOCOFF: 258 error = grfoff(dev); 259 break; 260 case GRFIOCSINFO: 261 error = grfsinfo(dev, (struct grfdyninfo *) data); 262 break; 263 case GRFGETVMODE: 264 return(gp->g_mode(gp, GM_GRFGETVMODE, data, 0, 0)); 265 case GRFSETVMODE: 266 error = gp->g_mode(gp, GM_GRFSETVMODE, data, 0, 0); 267 if (error == 0 && gp->g_itedev && !(gp->g_flags & GF_GRFON)) 268 ite_reinit(gp->g_itedev); 269 break; 270 case GRFGETNUMVM: 271 return(gp->g_mode(gp, GM_GRFGETNUMVM, data, 0, 0)); 272 /* 273 * these are all hardware dependant, and have to be resolved 274 * in the respective driver. 275 */ 276 case GRFIOCPUTCMAP: 277 case GRFIOCGETCMAP: 278 case GRFIOCSSPRITEPOS: 279 case GRFIOCGSPRITEPOS: 280 case GRFIOCSSPRITEINF: 281 case GRFIOCGSPRITEINF: 282 case GRFIOCGSPRITEMAX: 283 case GRFIOCBITBLT: 284 case GRFIOCSETMON: 285 case GRFTOGGLE: /* Toggles between Cirrus boards and native ECS on 286 Amiga. 15/11/94 ill */ 287 /* 288 * We need the minor dev number to get the overlay/image 289 * information for grf_ul. 290 */ 291 return(gp->g_mode(gp, GM_GRFIOCTL, data, cmd, dev)); 292 293 case GRFIOCBLANK: /* blank ioctl, IOCON/OFF will turn ite on */ 294 case FBIOSVIDEO: 295 error = gp->g_mode(gp, GM_GRFIOCTL, data, GRFIOCBLANK, dev); 296 if (!error) 297 gp->g_blank = *(int *)data; 298 return (error); 299 300 case FBIOGVIDEO: 301 *(int *)data = gp->g_blank; 302 return (0); 303 304 default: 305 #if NVIEW > 0 306 /* 307 * check to see whether it's a command recognized by the 308 * view code if the unit is 0 309 * XXX 310 */ 311 if (GRFUNIT(dev) == 0) { 312 extern const struct cdevsw view_cdevsw; 313 314 return((*view_cdevsw.d_ioctl)(dev, cmd, data, flag, l)); 315 } 316 #endif 317 error = EPASSTHROUGH; 318 break; 319 320 } 321 return(error); 322 } 323 324 /* 325 * map the contents of a graphics display card into process' 326 * memory space. 327 */ 328 paddr_t 329 grfmmap(dev_t dev, off_t off, int prot) 330 { 331 struct grf_softc *gp; 332 struct grfinfo *gi; 333 334 gp = grfsp[GRFUNIT(dev)]; 335 gi = &gp->g_display; 336 337 /* 338 * control registers 339 */ 340 if (off >= 0 && off < gi->gd_regsize) 341 return(((paddr_t)gi->gd_regaddr + off) >> PGSHIFT); 342 343 /* 344 * frame buffer 345 */ 346 if (off >= gi->gd_regsize && off < gi->gd_regsize+gi->gd_fbsize) { 347 off -= gi->gd_regsize; 348 return(((paddr_t)gi->gd_fbaddr + off) >> PGSHIFT); 349 } 350 /* bogus */ 351 return(-1); 352 } 353 354 int 355 grfon(dev_t dev) 356 { 357 struct grf_softc *gp; 358 359 gp = grfsp[GRFUNIT(dev)]; 360 361 if (gp->g_flags & GF_GRFON) 362 return(0); 363 364 gp->g_flags |= GF_GRFON; 365 if (gp->g_itedev != NODEV) 366 ite_off(gp->g_itedev, 3); 367 368 return(gp->g_mode(gp, (dev & GRFOVDEV) ? GM_GRFOVON : GM_GRFON, 369 NULL, 0, 0)); 370 } 371 372 int 373 grfoff(dev_t dev) 374 { 375 struct grf_softc *gp; 376 int error; 377 378 gp = grfsp[GRFUNIT(dev)]; 379 380 if ((gp->g_flags & GF_GRFON) == 0) 381 return(0); 382 383 gp->g_flags &= ~GF_GRFON; 384 error = gp->g_mode(gp, (dev & GRFOVDEV) ? GM_GRFOVOFF : GM_GRFOFF, 385 NULL, 0, 0); 386 387 /* 388 * Closely tied together no X's 389 */ 390 if (gp->g_itedev != NODEV) 391 ite_on(gp->g_itedev, 2); 392 393 return(error); 394 } 395 396 int 397 grfsinfo(dev_t dev, 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 #endif /* NGRF > 0 */ 414