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

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

1.1       nbrk        1: /*     $OpenBSD: agp_intel.c,v 1.4 2007/08/04 19:40:25 reyk Exp $      */
                      2: /*     $NetBSD: agp_intel.c,v 1.3 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_intel.c,v 1.4 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/agpio.h>
                     40: #include <sys/device.h>
                     41: #include <sys/agpio.h>
                     42:
                     43:
                     44: #include <dev/pci/pcivar.h>
                     45: #include <dev/pci/pcireg.h>
                     46: #include <dev/pci/vga_pcivar.h>
                     47: #include <dev/pci/agpvar.h>
                     48: #include <dev/pci/agpreg.h>
                     49:
                     50: #include <machine/bus.h>
                     51:
                     52: struct agp_intel_softc {
                     53:        u_int32_t       initial_aperture; /* aperture size at startup */
                     54:        struct agp_gatt *gatt;
                     55: };
                     56:
                     57:
                     58: static u_int32_t agp_intel_get_aperture(struct vga_pci_softc *);
                     59: static int agp_intel_set_aperture(struct vga_pci_softc *, u_int32_t);
                     60: static int agp_intel_bind_page(struct vga_pci_softc *, off_t, bus_addr_t);
                     61: static int agp_intel_unbind_page(struct vga_pci_softc *, off_t);
                     62: static void agp_intel_flush_tlb(struct vga_pci_softc *);
                     63:
                     64: struct agp_methods agp_intel_methods = {
                     65:        agp_intel_get_aperture,
                     66:        agp_intel_set_aperture,
                     67:        agp_intel_bind_page,
                     68:        agp_intel_unbind_page,
                     69:        agp_intel_flush_tlb,
                     70:        agp_generic_enable,
                     71:        agp_generic_alloc_memory,
                     72:        agp_generic_free_memory,
                     73:        agp_generic_bind_memory,
                     74:        agp_generic_unbind_memory,
                     75: };
                     76:
                     77: int
                     78: agp_intel_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
                     79:                 struct pci_attach_args *pchb_pa)
                     80: {
                     81:        struct agp_intel_softc *isc;
                     82:        struct agp_gatt *gatt;
                     83:        pcireg_t reg;
                     84:
                     85:        isc = malloc(sizeof *isc, M_DEVBUF, M_NOWAIT);
                     86:        if (isc == NULL) {
                     87:                printf(": can't allocate chipset-specific softc\n");
                     88:                return (ENOMEM);
                     89:        }
                     90:        memset(isc, 0, sizeof *isc);
                     91:
                     92:        sc->sc_methods = &agp_intel_methods;
                     93:        sc->sc_chipc = isc;
                     94:
                     95:        if (agp_map_aperture(sc, AGP_APBASE, PCI_MAPREG_TYPE_MEM) != 0) {
                     96:                printf(": can't map aperture\n");
                     97:                free(isc, M_DEVBUF);
                     98:                sc->sc_chipc = NULL;
                     99:                return (ENXIO);
                    100:        }
                    101:
                    102:        isc->initial_aperture = AGP_GET_APERTURE(sc);
                    103:
                    104:        for (;;) {
                    105:                gatt = agp_alloc_gatt(sc);
                    106:                if (gatt)
                    107:                        break;
                    108:
                    109:                /*
                    110:                 * Probably contigmalloc failure. Try reducing the
                    111:                 * aperture so that the gatt size reduces.
                    112:                 */
                    113:                if (AGP_SET_APERTURE(sc, AGP_GET_APERTURE(sc) / 2)) {
                    114:                        agp_generic_detach(sc);
                    115:                        printf(": failed to set aperture\n");
                    116:                        return (ENOMEM);
                    117:                }
                    118:        }
                    119:        isc->gatt = gatt;
                    120:
                    121:        /* Install the gatt. */
                    122:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_ATTBASE,
                    123:            gatt->ag_physical);
                    124:
                    125:        /* Enable things, clear errors etc. */
                    126:        /* XXXfvdl get rid of the magic constants */
                    127:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_AGPCTRL, 0x2280);
                    128:        reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_NBXCFG);
                    129:        reg &= ~(1 << 10);
                    130:        reg |=  (1 << 9);
                    131:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_NBXCFG, reg);
                    132:
                    133:        reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_STS);
                    134:        reg &= ~0x00ff0000;
                    135:        reg |= (7 << 16);
                    136:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_STS, reg);
                    137:
                    138:        return (0);
                    139: }
                    140:
                    141: #if 0
                    142: static int
                    143: agp_intel_detach(struct vga_pci_softc *sc)
                    144: {
                    145:        int error;
                    146:        pcireg_t reg;
                    147:        struct agp_intel_softc *isc = sc->sc_chipc;
                    148:
                    149:        error = agp_generic_detach(sc);
                    150:        if (error)
                    151:                return (error);
                    152:
                    153:        reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_NBXCFG);
                    154:        reg &= ~(1 << 9);
                    155:        printf("%s: set NBXCFG to %x\n", __FUNCTION__, reg);
                    156:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_NBXCFG, reg);
                    157:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_ATTBASE, 0);
                    158:        AGP_SET_APERTURE(sc, isc->initial_aperture);
                    159:        agp_free_gatt(sc, isc->gatt);
                    160:
                    161:        return (0);
                    162: }
                    163: #endif
                    164:
                    165: static u_int32_t
                    166: agp_intel_get_aperture(struct vga_pci_softc *sc)
                    167: {
                    168:        u_int32_t apsize;
                    169:
                    170:        apsize = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
                    171:            AGP_INTEL_APSIZE) & 0x1f;
                    172:
                    173:        /*
                    174:         * The size is determined by the number of low bits of
                    175:         * register APBASE which are forced to zero. The low 22 bits
                    176:         * are always forced to zero and each zero bit in the apsize
                    177:         * field just read forces the corresponding bit in the 27:22
                    178:         * to be zero. We calculate the aperture size accordingly.
                    179:         */
                    180:        return ((((apsize ^ 0x1f) << 22) | ((1 << 22) - 1)) + 1);
                    181: }
                    182:
                    183: static int
                    184: agp_intel_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
                    185: {
                    186:        u_int32_t apsize;
                    187:        pcireg_t reg;
                    188:
                    189:        /*
                    190:         * Reverse the magic from get_aperture.
                    191:         */
                    192:        apsize = ((aperture - 1) >> 22) ^ 0x1f;
                    193:
                    194:        /*
                    195:         * Double check for sanity.
                    196:         */
                    197:        if ((((apsize ^ 0x1f) << 22) | ((1 << 22) - 1)) + 1 != aperture)
                    198:                return (EINVAL);
                    199:
                    200:        reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_APSIZE);
                    201:        reg = (reg & 0xffffff00) | apsize;
                    202:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_APSIZE, reg);
                    203:
                    204:        return (0);
                    205: }
                    206:
                    207: static int
                    208: agp_intel_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
                    209: {
                    210:        struct agp_intel_softc *isc = sc->sc_chipc;
                    211:
                    212:        if (offset < 0 || offset >= (isc->gatt->ag_entries << AGP_PAGE_SHIFT))
                    213:                return (EINVAL);
                    214:
                    215:        isc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical | 0x17;
                    216:        return (0);
                    217: }
                    218:
                    219: static int
                    220: agp_intel_unbind_page(struct vga_pci_softc *sc, off_t offset)
                    221: {
                    222:        struct agp_intel_softc *isc = sc->sc_chipc;
                    223:
                    224:        if (offset < 0 || offset >= (isc->gatt->ag_entries << AGP_PAGE_SHIFT))
                    225:                return (EINVAL);
                    226:
                    227:        isc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
                    228:        return (0);
                    229: }
                    230:
                    231: static void
                    232: agp_intel_flush_tlb(struct vga_pci_softc *sc)
                    233: {
                    234:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_AGPCTRL, 0x2200);
                    235:        pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_AGPCTRL, 0x2280);
                    236: }

CVSweb