[BACK]Return to agp_via.c CVS log [TXT][DIR] Up to [local] / sys / dev / pci

Annotation of sys/dev/pci/agp_via.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: agp_via.c,v 1.3 2007/08/04 19:40:25 reyk Exp $        */
                      2: /*     $NetBSD: agp_via.c,v 1.2 2001/09/15 00:25:00 thorpej Exp $      */
                      3:
                      4: /*-
                      5:  * Copyright (c) 2000 Doug Rabson
                      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:  *
                     17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     18:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     19:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     20:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     21:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     22:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     23:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     24:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     25:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     26:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     27:  * SUCH DAMAGE.
                     28:  *
                     29:  *     $FreeBSD: src/sys/pci/agp_via.c,v 1.3 2001/07/05 21:28:47 jhb Exp $
                     30:  */
                     31:
                     32:
                     33: #include <sys/param.h>
                     34: #include <sys/systm.h>
                     35: #include <sys/malloc.h>
                     36: #include <sys/kernel.h>
                     37: #include <sys/lock.h>
                     38: #include <sys/proc.h>
                     39: #include <sys/conf.h>
                     40: #include <sys/device.h>
                     41: #include <sys/agpio.h>
                     42:
                     43: #include <dev/pci/pcivar.h>
                     44: #include <dev/pci/pcireg.h>
                     45: #include <dev/pci/vga_pcivar.h>
                     46: #include <dev/pci/agpvar.h>
                     47: #include <dev/pci/agpreg.h>
                     48:
                     49: #include <machine/bus.h>
                     50:
                     51: static u_int32_t agp_via_get_aperture(struct vga_pci_softc *);
                     52: static int agp_via_set_aperture(struct vga_pci_softc *, u_int32_t);
                     53: static int agp_via_bind_page(struct vga_pci_softc *, off_t, bus_addr_t);
                     54: static int agp_via_unbind_page(struct vga_pci_softc *, off_t);
                     55: static void agp_via_flush_tlb(struct vga_pci_softc *);
                     56:
                     57: struct agp_methods agp_via_methods = {
                     58:        agp_via_get_aperture,
                     59:        agp_via_set_aperture,
                     60:        agp_via_bind_page,
                     61:        agp_via_unbind_page,
                     62:        agp_via_flush_tlb,
                     63:        agp_generic_enable,
                     64:        agp_generic_alloc_memory,
                     65:        agp_generic_free_memory,
                     66:        agp_generic_bind_memory,
                     67:        agp_generic_unbind_memory,
                     68: };
                     69:
                     70: struct agp_via_softc {
                     71:        u_int32_t       initial_aperture; /* aperture size at startup */
                     72:        struct agp_gatt *gatt;
                     73: };
                     74:
                     75:
                     76: int
                     77: agp_via_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
                     78:               struct pci_attach_args *pchb_pa)
                     79: {
                     80:        struct agp_via_softc *asc;
                     81:        struct agp_gatt *gatt;
                     82:
                     83:        asc = malloc(sizeof *asc, M_DEVBUF, M_NOWAIT);
                     84:        if (asc == NULL) {
                     85:                printf(": can't allocate chipset-specific softc\n");
                     86:                return (ENOMEM);
                     87:        }
                     88:        memset(asc, 0, sizeof *asc);
                     89:        sc->sc_chipc = asc;
                     90:        sc->sc_methods = &agp_via_methods;
                     91:
                     92:        if (agp_map_aperture(sc, AGP_APBASE, PCI_MAPREG_TYPE_MEM) != 0) {
                     93:                printf(": can't map aperture\n");
                     94:                free(asc, M_DEVBUF);
                     95:                return (ENXIO);
                     96:        }
                     97:
                     98:        asc->initial_aperture = AGP_GET_APERTURE(sc);
                     99:
                    100:        for (;;) {
                    101:                gatt = agp_alloc_gatt(sc);
                    102:                if (gatt)
                    103:                        break;
                    104:
                    105:                /*
                    106:                 * Probably contigmalloc failure. Try reducing the
                    107:                 * aperture so that the gatt size reduces.
                    108:                 */
                    109:                if (AGP_SET_APERTURE(sc, AGP_GET_APERTURE(sc) / 2)) {
                    110:                        agp_generic_detach(sc);
                    111:                        printf(": can't set aperture size\n");
                    112:                        return (ENOMEM);
                    113:                }
                    114:        }
                    115:        asc->gatt = gatt;
                    116:
                    117:        /* Install the gatt. */
                    118:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_ATTBASE,
                    119:            gatt->ag_physical | 3);
                    120:
                    121:        /* Enable the aperture. */
                    122:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_GARTCTRL, 0x0000000f);
                    123:
                    124:        return (0);
                    125: }
                    126:
                    127: #if 0
                    128: static int
                    129: agp_via_detach(struct vga_pci_softc *sc)
                    130: {
                    131:        struct agp_via_softc *asc = sc->sc_chipc;
                    132:        int error;
                    133:
                    134:        error = agp_generic_detach(sc);
                    135:        if (error)
                    136:                return (error);
                    137:
                    138:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_GARTCTRL, 0);
                    139:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_ATTBASE, 0);
                    140:        AGP_SET_APERTURE(sc, asc->initial_aperture);
                    141:        agp_free_gatt(sc, asc->gatt);
                    142:
                    143:        return (0);
                    144: }
                    145: #endif
                    146:
                    147: static u_int32_t
                    148: agp_via_get_aperture(struct vga_pci_softc *sc)
                    149: {
                    150:        u_int32_t apsize;
                    151:
                    152:        apsize = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
                    153:            AGP_VIA_APSIZE) & 0x1f;
                    154:
                    155:        /*
                    156:         * The size is determined by the number of low bits of
                    157:         * register APBASE which are forced to zero. The low 20 bits
                    158:         * are always forced to zero and each zero bit in the apsize
                    159:         * field just read forces the corresponding bit in the 27:20
                    160:         * to be zero. We calculate the aperture size accordingly.
                    161:         */
                    162:        return ((((apsize ^ 0xff) << 20) | ((1 << 20) - 1)) + 1);
                    163: }
                    164:
                    165: static int
                    166: agp_via_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
                    167: {
                    168:        u_int32_t apsize;
                    169:        pcireg_t reg;
                    170:
                    171:        /*
                    172:         * Reverse the magic from get_aperture.
                    173:         */
                    174:        apsize = ((aperture - 1) >> 20) ^ 0xff;
                    175:
                    176:        /*
                    177:         * Double check for sanity.
                    178:         */
                    179:        if ((((apsize ^ 0xff) << 20) | ((1 << 20) - 1)) + 1 != aperture)
                    180:                return (EINVAL);
                    181:
                    182:        reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_VIA_APSIZE);
                    183:        reg &= ~0xff;
                    184:        reg |= apsize;
                    185:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_APSIZE, reg);
                    186:
                    187:        return (0);
                    188: }
                    189:
                    190: static int
                    191: agp_via_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
                    192: {
                    193:        struct agp_via_softc *asc = sc->sc_chipc;
                    194:
                    195:        if (offset < 0 || offset >= (asc->gatt->ag_entries << AGP_PAGE_SHIFT))
                    196:                return (EINVAL);
                    197:
                    198:        asc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical;
                    199:        return (0);
                    200: }
                    201:
                    202: static int
                    203: agp_via_unbind_page(struct vga_pci_softc *sc, off_t offset)
                    204: {
                    205:        struct agp_via_softc *asc = sc->sc_chipc;
                    206:
                    207:        if (offset < 0 || offset >= (asc->gatt->ag_entries << AGP_PAGE_SHIFT))
                    208:                return (EINVAL);
                    209:
                    210:        asc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
                    211:        return (0);
                    212: }
                    213:
                    214: static void
                    215: agp_via_flush_tlb(struct vga_pci_softc *sc)
                    216: {
                    217:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_GARTCTRL, 0x8f);
                    218:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_GARTCTRL, 0x0f);
                    219: }

CVSweb