[BACK]Return to vgafb_pci.c CVS log [TXT][DIR] Up to [local] / sys / arch / macppc / pci

Annotation of sys/arch/macppc/pci/vgafb_pci.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: vgafb_pci.c,v 1.18 2006/12/17 22:18:14 miod Exp $     */
        !             2: /*     $NetBSD: vga_pci.c,v 1.4 1996/12/05 01:39:38 cgd Exp $  */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * Author: Chris G. Demetriou
        !             9:  *
        !            10:  * Permission to use, copy, modify and distribute this software and
        !            11:  * its documentation is hereby granted, provided that both the copyright
        !            12:  * notice and this permission notice appear in all copies of the
        !            13:  * software, derivative works or modified versions, and any portions
        !            14:  * thereof, and that both notices appear in supporting documentation.
        !            15:  *
        !            16:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            17:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
        !            18:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            19:  *
        !            20:  * Carnegie Mellon requests users of this software to return to
        !            21:  *
        !            22:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
        !            23:  *  School of Computer Science
        !            24:  *  Carnegie Mellon University
        !            25:  *  Pittsburgh PA 15213-3890
        !            26:  *
        !            27:  * any improvements or extensions that they make and grant Carnegie the
        !            28:  * rights to redistribute these changes.
        !            29:  */
        !            30:
        !            31: #include <sys/param.h>
        !            32: #include <sys/systm.h>
        !            33: #include <sys/kernel.h>
        !            34: #include <sys/device.h>
        !            35: #include <sys/malloc.h>
        !            36:
        !            37: #ifndef i386
        !            38: #include <machine/autoconf.h>
        !            39: #endif
        !            40: #include <machine/pte.h>
        !            41:
        !            42: #include <dev/cons.h>
        !            43: #include <dev/pci/pcireg.h>
        !            44: #include <dev/pci/pcivar.h>
        !            45: #include <dev/pci/pcidevs.h>
        !            46:
        !            47: #include <dev/wscons/wsconsio.h>
        !            48: #include <dev/wscons/wsdisplayvar.h>
        !            49: #include <dev/rasops/rasops.h>
        !            50: #include <dev/wsfont/wsfont.h>
        !            51:
        !            52: #include <arch/macppc/pci/vgafbvar.h>
        !            53: #include <arch/macppc/pci/vgafb_pcivar.h>
        !            54:
        !            55: #define PCI_VENDORID(x) ((x) & 0xFFFF)
        !            56: #define PCI_CHIPID(x)   (((x) >> 16) & 0xFFFF)
        !            57:
        !            58: struct vgafb_pci_softc {
        !            59:        struct device sc_dev;
        !            60:
        !            61:        pcitag_t sc_pcitag;             /* PCI tag, in case we need it. */
        !            62:        struct vgafb_config *sc_vc;     /* VGA configuration */
        !            63: };
        !            64:
        !            65: int vgafb_pci_probe(struct pci_attach_args *pa, int id, u_int32_t *ioaddr,
        !            66:     u_int32_t *iosize, u_int32_t *memaddr, u_int32_t *memsize,
        !            67:     u_int32_t *cacheable, u_int32_t *mmioaddr, u_int32_t *mmiosize);
        !            68: int    vgafb_pci_match(struct device *, void *, void *);
        !            69: void   vgafb_pci_attach(struct device *, struct device *, void *);
        !            70:
        !            71: paddr_t        vgafbpcimmap(void *, off_t, int);
        !            72: int    vgafbpciioctl(void *, u_long, caddr_t, int, struct proc *);
        !            73:
        !            74: struct cfattach vgafb_pci_ca = {
        !            75:        sizeof(struct vgafb_pci_softc), (cfmatch_t)vgafb_pci_match, vgafb_pci_attach,
        !            76: };
        !            77:
        !            78: pcitag_t vgafb_pci_console_tag;
        !            79: struct vgafb_config vgafb_pci_console_vc;
        !            80:
        !            81: #if 0
        !            82: #define DEBUG_VGAFB
        !            83: #endif
        !            84:
        !            85: int
        !            86: vgafb_pci_probe(struct pci_attach_args *pa, int id, u_int32_t *ioaddr,
        !            87:     u_int32_t *iosize, u_int32_t *memaddr, u_int32_t *memsize,
        !            88:     u_int32_t *cacheable, u_int32_t *mmioaddr, u_int32_t *mmiosize)
        !            89: {
        !            90:        u_long addr;
        !            91:        u_int32_t size, tcacheable;
        !            92:        pci_chipset_tag_t pc = pa->pa_pc;
        !            93:        int retval;
        !            94:        int i;
        !            95:
        !            96:        *iosize   = 0x0;
        !            97:        *memsize  = 0x0;
        !            98:        *mmiosize = 0x0;
        !            99:        for (i = PCI_MAPREG_START; i <= PCI_MAPREG_PPB_END; i += 4) {
        !           100: #ifdef DEBUG_VGAFB
        !           101:                printf("vgafb confread %x %x\n",
        !           102:                        i, pci_conf_read(pc, pa->pa_tag, i));
        !           103: #endif
        !           104:                /* need to check more than just two base addresses? */
        !           105:                if (PCI_MAPREG_TYPE(pci_conf_read(pc, pa->pa_tag, i)) ==
        !           106:                    PCI_MAPREG_TYPE_IO) {
        !           107:                        retval = pci_io_find(pc, pa->pa_tag, i,
        !           108:                                &addr, &size);
        !           109:                        if (retval != 0) {
        !           110:                                continue;
        !           111:                        }
        !           112: #ifdef DEBUG_VGAFB
        !           113:        printf("vgafb_pci_probe: io %x addr %x size %x\n", i, addr, size);
        !           114: #endif
        !           115:                        if (*iosize == 0) {
        !           116:                                *ioaddr = addr;
        !           117:                                *iosize = size;
        !           118:                        }
        !           119:
        !           120:                } else {
        !           121:                        retval = pci_mem_find(pc, pa->pa_tag, i,
        !           122:                                &addr, &size, &tcacheable);
        !           123:                        if (retval != 0) {
        !           124:                                continue;
        !           125:                        }
        !           126: #ifdef DEBUG_VGAFB
        !           127:        printf("vgafb_pci_probe: mem %x addr %x size %x\n", i, addr, size);
        !           128: #endif
        !           129:                        if (size == 0 || addr == 0) {
        !           130:                                /* ignore this entry */
        !           131:                        } else if (*memsize == 0) {
        !           132:                                /*
        !           133:                                 * first memory slot found goes into memory,
        !           134:                                 * this is for the case of no mmio
        !           135:                                 */
        !           136:                                *memaddr = addr;
        !           137:                                *memsize = size;
        !           138:                                *cacheable = tcacheable;
        !           139:                        } else {
        !           140:                                /*
        !           141:                                 * Oh, we have a second 'memory'
        !           142:                                 * region, is this region the vga memory
        !           143:                                 * or mmio, we guess that memory is
        !           144:                                 * the larger of the two.
        !           145:                                 */
        !           146:                                 if (*memaddr > size) {
        !           147:                                        /* this is the mmio */
        !           148:                                        *mmioaddr = addr;
        !           149:                                        /* ATI driver maps 0x80000 mmio, grr */
        !           150:                                        if (size < 0x80000) {
        !           151:                                                size = 0x80000;
        !           152:                                        }
        !           153:                                        *mmiosize = size;
        !           154:                                 } else {
        !           155:                                        /* this is the memory */
        !           156:                                        *mmioaddr = *memaddr;
        !           157:                                        *memaddr = addr;
        !           158:                                        *mmiosize = *memsize;
        !           159:                                        *memsize = size;
        !           160:                                        *cacheable = tcacheable;
        !           161:                                        /* ATI driver maps 0x80000 mmio, grr */
        !           162:                                        if (*mmiosize < 0x80000) {
        !           163:                                                *mmiosize = 0x80000;
        !           164:                                        }
        !           165:                                 }
        !           166:                        }
        !           167:                }
        !           168:        }
        !           169: #ifdef DEBUG_VGAFB
        !           170:        printf("vgafb_pci_probe: id %x ioaddr %x, iosize %x, memaddr %x,\n memsize %x, mmioaddr %x, mmiosize %x\n",
        !           171:                id, *ioaddr, *iosize, *memaddr, *memsize, *mmioaddr, *mmiosize);
        !           172: #endif
        !           173:        if (*iosize == 0) {
        !           174:                if (id == 0) {
        !           175: #ifdef powerpc
        !           176:                        /* this is only used if on openfirmware system and
        !           177:                         * the device does not have a iobase config register,
        !           178:                         * eg CirrusLogic 5434 VGA.  (they hardcode iobase to 0
        !           179:                         * thus giving standard PC addresses for the registers)
        !           180:                         */
        !           181:                        int s;
        !           182:                        u_int32_t sizedata;
        !           183:
        !           184:                        /*
        !           185:                         * Open Firmware (yuck) shuts down devices before
        !           186:                         * entering a program so we need to bring them back
        !           187:                         * 'online' to respond to bus accesses... so far
        !           188:                         * this is true on the power.4e.
        !           189:                         */
        !           190:                        s = splhigh();
        !           191:                        sizedata = pci_conf_read(pc, pa->pa_tag,
        !           192:                                PCI_COMMAND_STATUS_REG);
        !           193:                        sizedata |= (PCI_COMMAND_MASTER_ENABLE |
        !           194:                                     PCI_COMMAND_IO_ENABLE |
        !           195:                                     PCI_COMMAND_PARITY_ENABLE |
        !           196:                                     PCI_COMMAND_SERR_ENABLE);
        !           197:                        pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
        !           198:                                sizedata);
        !           199:                        splx(s);
        !           200:
        !           201: #endif
        !           202:                        /* if this is the first card, allow it
        !           203:                         * to be accessed in vga iospace
        !           204:                         */
        !           205:                        *ioaddr = 0;
        !           206:                        *iosize = 0x10000; /* 64k, good as any */
        !           207:                } else {
        !           208:                        /* iospace not available, assume 640x480, pray */
        !           209:                        *ioaddr = 0;
        !           210:                        *iosize = 0;
        !           211:                }
        !           212:        }
        !           213: #ifdef DEBUG_VGAFB
        !           214:        printf("vgafb_pci_probe: id %x ioaddr %x, iosize %x, memaddr %x,\n memsize %x, mmioaddr %x, mmiosize %x\n",
        !           215:                id, *ioaddr, *iosize, *memaddr, *memsize, *mmioaddr, *mmiosize);
        !           216: #endif
        !           217:
        !           218:        /* io and mmio spaces are not required to attach */
        !           219:        if (/* *iosize == 0 || */ *memsize == 0 /* || *mmiosize == 0 */)
        !           220:                return (0);
        !           221:
        !           222:        return (1);
        !           223: }
        !           224:
        !           225: int
        !           226: vgafb_pci_match(parent, match, aux)
        !           227:        struct device *parent;
        !           228:        void *match;
        !           229:        void *aux;
        !           230: {
        !           231:        struct pci_attach_args *pa = aux;
        !           232:        int potential;
        !           233:        static int id = 0;
        !           234:        int myid;
        !           235:
        !           236:        myid = id;
        !           237:
        !           238:        potential = 0;
        !           239:
        !           240:        /*
        !           241:         * If it's prehistoric/vga or display/vga, we might match.
        !           242:         * For the console device, this is jut a sanity check.
        !           243:         */
        !           244:        if (PCI_CLASS(pa->pa_class) == PCI_CLASS_PREHISTORIC &&
        !           245:            PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_PREHISTORIC_VGA)
        !           246:                potential = 1;
        !           247:        if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY &&
        !           248:             PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA)
        !           249:                potential = 1;
        !           250:        if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY &&
        !           251:             PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_MISC)
        !           252:                potential = 1;
        !           253:
        !           254:        if (!potential)
        !           255:                return (0);
        !           256:
        !           257:        /* If it's the console, we have a winner! */
        !           258:        if (!bcmp(&pa->pa_tag, &vgafb_pci_console_tag, sizeof(pa->pa_tag))) {
        !           259:                id++;
        !           260:                return (1);
        !           261:        }
        !           262:
        !           263: #ifdef DEBUG_VGAFB
        !           264:        {
        !           265:        int i;
        !           266:                pci_chipset_tag_t pc = pa->pa_pc;
        !           267:                for (i = 0x10; i < 0x24; i+=4) {
        !           268:                        printf("vgafb confread %x %x\n",
        !           269:                                i, pci_conf_read(pc, pa->pa_tag, i));
        !           270:                }
        !           271:        }
        !           272: #endif
        !           273:
        !           274:        return (0);
        !           275: }
        !           276:
        !           277: void
        !           278: vgafb_pci_attach(struct device *parent, struct device  *self, void *aux)
        !           279: {
        !           280:        struct pci_attach_args *pa = aux;
        !           281:        struct vgafb_pci_softc *sc = (struct vgafb_pci_softc *)self;
        !           282:        struct vgafb_config *vc;
        !           283:        u_int32_t memaddr, memsize, cacheable;
        !           284:        u_int32_t ioaddr, iosize;
        !           285:        u_int32_t mmioaddr, mmiosize;
        !           286:        int console;
        !           287:        static int id = 0;
        !           288:        int myid;
        !           289:
        !           290:        myid = id;
        !           291:
        !           292:        vgafb_pci_probe(pa, myid, &ioaddr, &iosize,
        !           293:                &memaddr, &memsize, &cacheable, &mmioaddr, &mmiosize);
        !           294:
        !           295:
        !           296:        console = (!bcmp(&pa->pa_tag, &vgafb_pci_console_tag, sizeof(pa->pa_tag)));
        !           297:        if (console)
        !           298:                vc = sc->sc_vc = &vgafb_pci_console_vc;
        !           299:        else {
        !           300:                vc = sc->sc_vc = (struct vgafb_config *)
        !           301:                    malloc(sizeof(struct vgafb_config), M_DEVBUF, M_WAITOK);
        !           302:
        !           303:                /* set up bus-independent VGA configuration */
        !           304:                vgafb_common_setup(pa->pa_iot, pa->pa_memt, vc,
        !           305:                ioaddr, iosize, memaddr, memsize, mmioaddr, mmiosize);
        !           306:        }
        !           307:        vc->vc_mmap = vgafbpcimmap;
        !           308:        vc->vc_ioctl = vgafbpciioctl;
        !           309:        vc->membase = memaddr;
        !           310:        vc->memsize = memsize;
        !           311:        vc->mmiobase = mmioaddr;
        !           312:        vc->mmiosize = mmiosize;
        !           313:
        !           314:        sc->sc_pcitag = pa->pa_tag;
        !           315:
        !           316:        if (iosize == 0)
        !           317:                printf (", no io");
        !           318:
        !           319:        if (mmiosize != 0)
        !           320:                printf (", mmio");
        !           321:
        !           322:        printf("\n");
        !           323:
        !           324:        vgafb_wsdisplay_attach(self, vc, console);
        !           325:        id++;
        !           326: }
        !           327:
        !           328: void
        !           329: vgafb_pci_console(bus_space_tag_t iot, u_int32_t ioaddr, u_int32_t iosize,
        !           330:     bus_space_tag_t  memt, u_int32_t memaddr, u_int32_t memsize,
        !           331:     pci_chipset_tag_t pc, int bus, int device, int function)
        !           332: {
        !           333:        struct vgafb_config *vc = &vgafb_pci_console_vc;
        !           334:        u_int32_t mmioaddr;
        !           335:        u_int32_t mmiosize;
        !           336:        static struct pci_attach_args spa;
        !           337:        struct pci_attach_args *pa = &spa;
        !           338:
        !           339:        /* for later recognition */
        !           340:        vgafb_pci_console_tag = pci_make_tag(pc, bus, device, function);
        !           341:
        !           342:        pa->pa_iot = iot;
        !           343:        pa->pa_memt = memt;
        !           344:        pa->pa_tag = vgafb_pci_console_tag;
        !           345:        /*
        !           346:        pa->pa_pc = XXX;
        !           347:         */
        !           348:
        !           349: /* XXX probe pci before pci bus config? */
        !           350:
        !           351:        mmioaddr =0;
        !           352:        mmiosize =0;
        !           353: #if 0
        !           354:        vgafb_pci_probe(pa, 0, &ioaddr, &iosize,
        !           355:                &memaddr, &memsize, &cacheable, mmioaddr, mmiosize);
        !           356: #endif
        !           357:
        !           358:
        !           359:        /* set up bus-independent VGA configuration */
        !           360:        vgafb_common_setup(iot, memt, vc,
        !           361:                ioaddr, iosize, memaddr, memsize, mmioaddr, mmiosize);
        !           362:
        !           363:        vgafb_cnattach(iot, memt, pc, bus, device, function);
        !           364:        vc->nscreens++;
        !           365: }
        !           366:
        !           367: int
        !           368: vgafbpciioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
        !           369: {
        !           370:        struct vgafb_pci_softc *sc = v;
        !           371:
        !           372:        return (vgafb_ioctl(sc->sc_vc, cmd, data, flag, p));
        !           373: }
        !           374:
        !           375: paddr_t
        !           376: vgafbpcimmap(void *v, off_t offset, int prot)
        !           377: {
        !           378:        struct vgafb_pci_softc *sc = v;
        !           379:
        !           380:        return (vgafb_mmap(sc->sc_vc, offset, prot));
        !           381: }
        !           382:
        !           383: int
        !           384: vgafb_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
        !           385:     int *curxp, int *curyp, long *attrp)
        !           386: {
        !           387:        struct vgafb_config *vc = v;
        !           388:        long defattr;
        !           389:
        !           390:        if (vc->nscreens > 0)
        !           391:                return (ENOMEM);
        !           392:
        !           393:        *cookiep = &vc->dc_rinfo; /* one and only for now */
        !           394:        *curxp = 0;
        !           395:        *curyp = 0;
        !           396:        vc->dc_rinfo.ri_ops.alloc_attr(&vc->dc_rinfo, 0, 0, 0, &defattr);
        !           397:        *attrp = defattr;
        !           398:        vc->nscreens++;
        !           399:        return (0);
        !           400: }
        !           401:
        !           402: void
        !           403: vgafb_free_screen(void *v, void *cookie)
        !           404: {
        !           405:        struct vgafb_config *vc = v;
        !           406:
        !           407:        if (vc == &vgafb_pci_console_vc)
        !           408:                panic("vgafb_free_screen: console");
        !           409:
        !           410:        vc->nscreens--;
        !           411: }
        !           412:
        !           413: int
        !           414: vgafb_show_screen(void *v, void *cookie, int waitok,
        !           415:     void (*cb)(void *, int, int), void *cbarg)
        !           416: {
        !           417:
        !           418:        return (0);
        !           419: }

CVSweb