[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     ! 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