1 /* $NetBSD: grf_obio.c,v 1.50 2003/07/15 02:43:25 lukem Exp $ */ 2 3 /* 4 * Copyright (C) 1998 Scott Reynolds 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 /* 30 * Copyright (c) 1995 Allen Briggs. All rights reserved. 31 * 32 * Redistribution and use in source and binary forms, with or without 33 * modification, are permitted provided that the following conditions 34 * are met: 35 * 1. Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * 2. Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in the 39 * documentation and/or other materials provided with the distribution. 40 * 3. All advertising materials mentioning features or use of this software 41 * must display the following acknowledgement: 42 * This product includes software developed by Allen Briggs. 43 * 4. The name of the author may not be used to endorse or promote products 44 * derived from this software without specific prior written permission. 45 * 46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 47 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 48 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 49 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 50 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 51 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 52 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 53 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 54 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 55 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 */ 57 /* 58 * Graphics display driver for the Macintosh internal video for machines 59 * that don't map it into a fake nubus card. 60 */ 61 62 #include <sys/cdefs.h> 63 __KERNEL_RCSID(0, "$NetBSD: grf_obio.c,v 1.50 2003/07/15 02:43:25 lukem Exp $"); 64 65 #include <sys/param.h> 66 #include <sys/device.h> 67 #include <sys/ioctl.h> 68 #include <sys/file.h> 69 #include <sys/malloc.h> 70 #include <sys/mman.h> 71 #include <sys/proc.h> 72 #include <sys/systm.h> 73 74 #include <machine/autoconf.h> 75 #include <machine/bus.h> 76 #include <machine/cpu.h> 77 #include <machine/grfioctl.h> 78 #include <machine/viareg.h> 79 80 #include <mac68k/nubus/nubus.h> 81 #include <mac68k/obio/obiovar.h> 82 #include <mac68k/dev/grfvar.h> 83 84 extern u_int32_t mac68k_vidphys; 85 extern u_int32_t mac68k_vidlen; 86 extern long videoaddr; 87 extern long videorowbytes; 88 extern long videobitdepth; 89 extern u_long videosize; 90 91 static int grfiv_mode __P((struct grf_softc *gp, int cmd, void *arg)); 92 static int grfiv_match __P((struct device *, struct cfdata *, void *)); 93 static void grfiv_attach __P((struct device *, struct device *, void *)); 94 95 CFATTACH_DECL(intvid, sizeof(struct grfbus_softc), 96 grfiv_match, grfiv_attach, NULL, NULL); 97 98 #define DAFB_BASE 0xf9000000 99 #define DAFB_CONTROL_BASE 0xf9800000 100 #define CIVIC_BASE 0x50100000 101 #define CIVIC_CONTROL_BASE 0x50036000 102 #define VALKYRIE_BASE 0xf9000000 103 #define VALKYRIE_CONTROL_BASE 0x50f2a000 104 105 static int 106 grfiv_match(parent, cf, aux) 107 struct device *parent; 108 struct cfdata *cf; 109 void *aux; 110 { 111 struct obio_attach_args *oa = (struct obio_attach_args *)aux; 112 bus_space_handle_t bsh; 113 int found; 114 u_int base; 115 116 found = 1; 117 118 switch (current_mac_model->class) { 119 case MACH_CLASSQ2: 120 if (current_mac_model->machineid != MACH_MACLC575) { 121 base = VALKYRIE_CONTROL_BASE; 122 123 if (bus_space_map(oa->oa_tag, base, 0x40, 0, &bsh)) 124 return 0; 125 126 /* Disable interrupts */ 127 bus_space_write_1(oa->oa_tag, bsh, 0x18, 0x1); 128 129 bus_space_unmap(oa->oa_tag, bsh, 0x40); 130 break; 131 } 132 /* 133 * Note: the only system in this class that does not have 134 * the Valkyrie chip -- at least, that we know of -- is 135 * the Performa/LC 57x series. This system has a version 136 * of the DAFB controller, instead. 137 * 138 * If this assumption proves false, we'll have to be more 139 * intelligent here. 140 */ 141 /*FALLTHROUGH*/ 142 case MACH_CLASSQ: 143 /* 144 * Assume DAFB for all of these, unless we can't 145 * access the memory. 146 */ 147 base = DAFB_CONTROL_BASE; 148 149 if (bus_space_map(oa->oa_tag, base, 0x20, 0, &bsh)) 150 return 0; 151 152 if (mac68k_bus_space_probe(oa->oa_tag, bsh, 0x1c, 4) == 0) { 153 bus_space_unmap(oa->oa_tag, bsh, 0x20); 154 return 0; 155 } 156 157 bus_space_unmap(oa->oa_tag, bsh, 0x20); 158 159 if (bus_space_map(oa->oa_tag, base + 0x100, 0x20, 0, &bsh)) 160 return 0; 161 162 if (mac68k_bus_space_probe(oa->oa_tag, bsh, 0x04, 4) == 0) { 163 bus_space_unmap(oa->oa_tag, bsh, 0x20); 164 return 0; 165 } 166 167 /* Disable interrupts */ 168 bus_space_write_4(oa->oa_tag, bsh, 0x04, 0); 169 170 /* Clear any interrupts */ 171 bus_space_write_4(oa->oa_tag, bsh, 0x0C, 0); 172 bus_space_write_4(oa->oa_tag, bsh, 0x10, 0); 173 bus_space_write_4(oa->oa_tag, bsh, 0x14, 0); 174 175 bus_space_unmap(oa->oa_tag, bsh, 0x20); 176 break; 177 case MACH_CLASSAV: 178 base = CIVIC_CONTROL_BASE; 179 180 if (bus_space_map(oa->oa_tag, base, 0x1000, 0, &bsh)) 181 return 0; 182 183 /* Disable interrupts */ 184 bus_space_write_1(oa->oa_tag, bsh, 0x120, 0); 185 186 bus_space_unmap(oa->oa_tag, bsh, 0x1000); 187 break; 188 case MACH_CLASSIIci: 189 case MACH_CLASSIIsi: 190 if (mac68k_vidlen == 0 || 191 (via2_reg(rMonitor) & RBVMonitorMask) == RBVMonIDNone) 192 found = 0; 193 break; 194 default: 195 if (mac68k_vidlen == 0) 196 found = 0; 197 break; 198 } 199 200 return found; 201 } 202 203 static void 204 grfiv_attach(parent, self, aux) 205 struct device *parent, *self; 206 void *aux; 207 { 208 struct obio_attach_args *oa = (struct obio_attach_args *)aux; 209 struct grfbus_softc *sc; 210 struct grfmode *gm; 211 u_long base, length; 212 u_int32_t vbase1, vbase2; 213 214 sc = (struct grfbus_softc *)self; 215 216 sc->card_id = 0; 217 218 switch (current_mac_model->class) { 219 case MACH_CLASSQ2: 220 if (current_mac_model->machineid != MACH_MACLC575) { 221 sc->sc_basepa = VALKYRIE_BASE; 222 length = 0x00100000; /* 1MB */ 223 224 if (sc->sc_basepa <= mac68k_vidphys && 225 mac68k_vidphys < (sc->sc_basepa + length)) { 226 sc->sc_fbofs = mac68k_vidphys - sc->sc_basepa; 227 } else { 228 sc->sc_basepa = m68k_trunc_page(mac68k_vidphys); 229 sc->sc_fbofs = m68k_page_offset(mac68k_vidphys); 230 length = mac68k_vidlen + sc->sc_fbofs; 231 } 232 233 printf(" @ %lx: Valkyrie video subsystem\n", 234 sc->sc_basepa + sc->sc_fbofs); 235 break; 236 } 237 /* See note in grfiv_match() */ 238 /*FALLTHROUGH*/ 239 case MACH_CLASSQ: 240 base = DAFB_CONTROL_BASE; 241 sc->sc_tag = oa->oa_tag; 242 if (bus_space_map(sc->sc_tag, base, 0x20, 0, &sc->sc_regh)) { 243 printf(": failed to map DAFB register space\n"); 244 return; 245 } 246 247 sc->sc_basepa = DAFB_BASE; 248 length = 0x00100000; /* 1MB */ 249 250 /* Compute the current frame buffer offset */ 251 vbase1 = bus_space_read_4(sc->sc_tag, sc->sc_regh, 0x0) & 0xfff; 252 #if 1 253 /* 254 * XXX The following exists because the DAFB v7 in these 255 * systems doesn't return reasonable values to use for fbofs. 256 * Ken'ichi Ishizaka gets credit for this hack. (sar 19990426) 257 * (Does this get us the correct result for _all_ DAFB- 258 * equipped systems and monitor combinations? It seems 259 * possible, if not likely...) 260 */ 261 switch (current_mac_model->machineid) { 262 case MACH_MACLC475: 263 case MACH_MACLC475_33: 264 case MACH_MACLC575: 265 case MACH_MACQ605: 266 case MACH_MACQ605_33: 267 vbase1 &= 0x3f; 268 break; 269 } 270 #endif 271 vbase2 = bus_space_read_4(sc->sc_tag, sc->sc_regh, 0x4) & 0xf; 272 sc->sc_fbofs = (vbase1 << 9) | (vbase2 << 5); 273 274 printf(" @ %lx: DAFB video subsystem, monitor sense %x\n", 275 sc->sc_basepa + sc->sc_fbofs, 276 (bus_space_read_4(sc->sc_tag, sc->sc_regh, 0x1c) & 0x7)); 277 278 bus_space_unmap(sc->sc_tag, sc->sc_regh, 0x20); 279 break; 280 case MACH_CLASSAV: 281 sc->sc_basepa = CIVIC_BASE; 282 length = 0x00200000; /* 2MB */ 283 if (mac68k_vidphys >= sc->sc_basepa && 284 mac68k_vidphys < (sc->sc_basepa + length)) { 285 sc->sc_fbofs = mac68k_vidphys - sc->sc_basepa; 286 } else { 287 sc->sc_basepa = m68k_trunc_page(mac68k_vidphys); 288 sc->sc_fbofs = m68k_page_offset(mac68k_vidphys); 289 length = mac68k_vidlen + sc->sc_fbofs; 290 } 291 292 printf(" @ %lx: CIVIC video subsystem\n", 293 sc->sc_basepa + sc->sc_fbofs); 294 break; 295 case MACH_CLASSIIci: 296 case MACH_CLASSIIsi: 297 sc->sc_basepa = m68k_trunc_page(mac68k_vidphys); 298 sc->sc_fbofs = m68k_page_offset(mac68k_vidphys); 299 length = mac68k_vidlen + sc->sc_fbofs; 300 301 printf(" @ %lx: RBV video subsystem, ", 302 sc->sc_basepa + sc->sc_fbofs); 303 switch (via2_reg(rMonitor) & RBVMonitorMask) { 304 case RBVMonIDBWP: 305 printf("15\" monochrome portrait"); 306 break; 307 case RBVMonIDRGB12: 308 printf("12\" color"); 309 break; 310 case RBVMonIDRGB15: 311 printf("15\" color"); 312 break; 313 case RBVMonIDStd: 314 printf("Macintosh II"); 315 break; 316 default: 317 printf("unrecognized"); 318 break; 319 } 320 printf(" display\n"); 321 322 break; 323 default: 324 sc->sc_basepa = m68k_trunc_page(mac68k_vidphys); 325 sc->sc_fbofs = m68k_page_offset(mac68k_vidphys); 326 length = mac68k_vidlen + sc->sc_fbofs; 327 328 printf(" @ %lx: On-board video\n", 329 sc->sc_basepa + sc->sc_fbofs); 330 break; 331 } 332 333 if (bus_space_map(sc->sc_tag, sc->sc_basepa, length, 0, 334 &sc->sc_handle)) { 335 printf("%s: failed to map video RAM\n", sc->sc_dev.dv_xname); 336 return; 337 } 338 339 if (sc->sc_basepa <= mac68k_vidphys && 340 mac68k_vidphys < (sc->sc_basepa + length)) 341 videoaddr = sc->sc_handle.base + sc->sc_fbofs; /* XXX hack */ 342 343 gm = &(sc->curr_mode); 344 gm->mode_id = 0; 345 gm->psize = videobitdepth; 346 gm->ptype = 0; 347 gm->width = videosize & 0xffff; 348 gm->height = (videosize >> 16) & 0xffff; 349 gm->rowbytes = videorowbytes; 350 gm->hres = 80; /* XXX hack */ 351 gm->vres = 80; /* XXX hack */ 352 gm->fbsize = gm->height * gm->rowbytes; 353 gm->fbbase = (caddr_t)sc->sc_handle.base; /* XXX yet another hack */ 354 gm->fboff = sc->sc_fbofs; 355 356 /* Perform common video attachment. */ 357 grf_establish(sc, NULL, grfiv_mode); 358 } 359 360 static int 361 grfiv_mode(sc, cmd, arg) 362 struct grf_softc *sc; 363 int cmd; 364 void *arg; 365 { 366 switch (cmd) { 367 case GM_GRFON: 368 case GM_GRFOFF: 369 return 0; 370 case GM_CURRMODE: 371 break; 372 case GM_NEWMODE: 373 break; 374 case GM_LISTMODES: 375 break; 376 } 377 return EINVAL; 378 } 379