[BACK]Return to grf_iv.c CVS log [TXT][DIR] Up to [local] / sys / arch / mac68k / dev

Annotation of sys/arch/mac68k/dev/grf_iv.c, Revision 1.1.1.1

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

CVSweb