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

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

1.1       nbrk        1: /*     $OpenBSD: agp_i810.c,v 1.15 2007/08/04 19:40:25 reyk Exp $      */
                      2: /*     $NetBSD: agp_i810.c,v 1.15 2003/01/31 00:07:39 thorpej Exp $    */
                      3:
                      4: /*-
                      5:  * Copyright (c) 2000 Doug Rabson
                      6:  * Copyright (c) 2000 Ruslan Ermilov
                      7:  * All rights reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  *
                     18:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     19:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     20:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     21:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     22:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     23:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     24:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     25:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     26:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     27:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     28:  * SUCH DAMAGE.
                     29:  *
                     30:  *     $FreeBSD: src/sys/pci/agp_i810.c,v 1.4 2001/07/05 21:28:47 jhb Exp $
                     31:  */
                     32:
                     33:
                     34: #include <sys/param.h>
                     35: #include <sys/systm.h>
                     36: #include <sys/malloc.h>
                     37: #include <sys/kernel.h>
                     38: #include <sys/lock.h>
                     39: #include <sys/proc.h>
                     40: #include <sys/device.h>
                     41: #include <sys/conf.h>
                     42: #include <sys/agpio.h>
                     43:
                     44: #include <dev/pci/pcivar.h>
                     45: #include <dev/pci/pcireg.h>
                     46: #include <dev/pci/pcidevs.h>
                     47: #include <dev/pci/agpvar.h>
                     48: #include <dev/pci/agpreg.h>
                     49: #include <dev/pci/vga_pcivar.h>
                     50:
                     51: #include <machine/bus.h>
                     52:
                     53: #define READ1(off)     bus_space_read_1(isc->bst, isc->bsh, off)
                     54: #define READ4(off)     bus_space_read_4(isc->bst, isc->bsh, off)
                     55: #define WRITE4(off,v)  bus_space_write_4(isc->bst, isc->bsh, off, v)
                     56: #define WRITEGTT(off,v)        bus_space_write_4(isc->gtt_bst, isc->gtt_bsh, off, v)
                     57:
                     58: #define WRITE_GATT(off, v)     agp_i810_write_gatt(isc, off, v)
                     59:
                     60: enum {
                     61:        CHIP_I810       = 0,    /* i810/i815 */
                     62:        CHIP_I830       = 1,    /* i830/i845 */
                     63:        CHIP_I855       = 2,    /* i852GM/i855GM/i865G */
                     64:        CHIP_I915       = 3,    /* i915G/i915GM */
                     65:        CHIP_I965       = 4     /* i965/i965GM */
                     66: };
                     67:
                     68: struct agp_i810_softc {
                     69:        struct agp_gatt *gatt;
                     70:        int chiptype;                   /* i810-like or i830 */
                     71:        u_int32_t dcache_size;          /* i810 only */
                     72:        u_int32_t stolen;               /* number of i830/845 gtt entries
                     73:                                           for stolen memory */
                     74:        bus_space_tag_t bst;            /* bus_space tag */
                     75:        bus_space_handle_t bsh;         /* bus_space handle */
                     76:        bus_size_t bsz;                 /* bus_space size */
                     77:        bus_space_tag_t gtt_bst;        /* GATT bus_space tag */
                     78:        bus_space_handle_t gtt_bsh;     /* GATT bus_space handle */
                     79:        struct pci_attach_args bridge_pa;
                     80: };
                     81:
                     82: u_int32_t agp_i810_get_aperture(struct vga_pci_softc *);
                     83: int    agp_i810_set_aperture(struct vga_pci_softc *, u_int32_t);
                     84: int    agp_i810_bind_page(struct vga_pci_softc *, off_t, bus_addr_t);
                     85: int    agp_i810_unbind_page(struct vga_pci_softc *, off_t);
                     86: void   agp_i810_flush_tlb(struct vga_pci_softc *);
                     87: int    agp_i810_enable(struct vga_pci_softc *, u_int32_t mode);
                     88: struct agp_memory *
                     89:        agp_i810_alloc_memory(struct vga_pci_softc *, int, vsize_t);
                     90: int    agp_i810_free_memory(struct vga_pci_softc *, struct agp_memory *);
                     91: int    agp_i810_bind_memory(struct vga_pci_softc *, struct agp_memory *,
                     92:            off_t);
                     93: int    agp_i810_unbind_memory(struct vga_pci_softc *, struct agp_memory *);
                     94: void   agp_i810_write_gatt(struct agp_i810_softc *, bus_size_t, u_int32_t);
                     95:
                     96: struct agp_methods agp_i810_methods = {
                     97:        agp_i810_get_aperture,
                     98:        agp_i810_set_aperture,
                     99:        agp_i810_bind_page,
                    100:        agp_i810_unbind_page,
                    101:        agp_i810_flush_tlb,
                    102:        agp_i810_enable,
                    103:        agp_i810_alloc_memory,
                    104:        agp_i810_free_memory,
                    105:        agp_i810_bind_memory,
                    106:        agp_i810_unbind_memory,
                    107: };
                    108:
                    109: int
                    110: agp_i810_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
                    111:                struct pci_attach_args *pchb_pa)
                    112: {
                    113:        struct agp_i810_softc *isc;
                    114:        struct agp_gatt *gatt;
                    115:        bus_addr_t mmaddr, gmaddr;
                    116:        int error;
                    117:        u_int memtype = 0;
                    118:
                    119:        isc = malloc(sizeof *isc, M_DEVBUF, M_NOWAIT);
                    120:        if (isc == NULL) {
                    121:                printf(": can't allocate chipset-specific softc\n");
                    122:                return (ENOMEM);
                    123:        }
                    124:        memset(isc, 0, sizeof *isc);
                    125:        sc->sc_chipc = isc;
                    126:        sc->sc_methods = &agp_i810_methods;
                    127:        memcpy(&isc->bridge_pa, pchb_pa, sizeof *pchb_pa);
                    128:
                    129:        switch (PCI_PRODUCT(pa->pa_id)) {
                    130:        case PCI_PRODUCT_INTEL_82810_GC:
                    131:        case PCI_PRODUCT_INTEL_82810_DC100_GC:
                    132:        case PCI_PRODUCT_INTEL_82810E_GC:
                    133:        case PCI_PRODUCT_INTEL_82815_FULL_GRAPH:
                    134:                isc->chiptype = CHIP_I810;
                    135:                break;
                    136:        case PCI_PRODUCT_INTEL_82830MP_IV:
                    137:        case PCI_PRODUCT_INTEL_82845G_IGD:
                    138:                isc->chiptype = CHIP_I830;
                    139:                break;
                    140:        case PCI_PRODUCT_INTEL_82852GM_AGP:
                    141:        case PCI_PRODUCT_INTEL_82865_IGD:
                    142:                isc->chiptype = CHIP_I855;
                    143:                break;
                    144:        case PCI_PRODUCT_INTEL_82915G_IV:
                    145:        case PCI_PRODUCT_INTEL_82915GM_IGD:
                    146:        case PCI_PRODUCT_INTEL_82945G_IGD_1:
                    147:        case PCI_PRODUCT_INTEL_82945GM_IGD:
                    148:                isc->chiptype = CHIP_I915;
                    149:                break;
                    150:        case PCI_PRODUCT_INTEL_82965_IGD_1:
                    151:        case PCI_PRODUCT_INTEL_82965GM_IGD_1:
                    152:                isc->chiptype = CHIP_I965;
                    153:                break;
                    154:        }
                    155:
                    156:        switch (isc->chiptype) {
                    157:        case CHIP_I915:
                    158:                gmaddr = AGP_I915_GMADR;
                    159:                mmaddr = AGP_I915_MMADR;
                    160:                break;
                    161:        case CHIP_I965:
                    162:                gmaddr = AGP_I965_GMADR;
                    163:                mmaddr = AGP_I965_MMADR;
                    164:                memtype = PCI_MAPREG_MEM_TYPE_64BIT;
                    165:                break;
                    166:        default:
                    167:                gmaddr = AGP_APBASE;
                    168:                mmaddr = AGP_I810_MMADR;
                    169:                break;
                    170:        }
                    171:
                    172:        error = agp_map_aperture(sc, gmaddr, memtype);
                    173:        if (error != 0) {
                    174:                printf(": can't map aperture\n");
                    175:                free(isc, M_DEVBUF);
                    176:                return (error);
                    177:        }
                    178:
                    179:        error = pci_mapreg_map(pa, mmaddr, memtype, 0,
                    180:            &isc->bst, &isc->bsh, NULL, &isc->bsz, 0);
                    181:        if (error != 0) {
                    182:                printf(": can't map mmadr registers\n");
                    183:                return (error);
                    184:        }
                    185:
                    186:        if (isc->chiptype == CHIP_I915) {
                    187:                error = pci_mapreg_map(pa, AGP_I915_GTTADR, memtype,
                    188:                    0, &isc->gtt_bst, &isc->gtt_bsh, NULL, NULL, 0);
                    189:                if (error != 0) {
                    190:                        printf(": can't map gatt registers\n");
                    191:                        agp_generic_detach(sc);
                    192:                        return (error);
                    193:                }
                    194:        }
                    195:
                    196:        gatt = malloc(sizeof(struct agp_gatt), M_DEVBUF, M_NOWAIT);
                    197:        if (!gatt) {
                    198:                agp_generic_detach(sc);
                    199:                return (ENOMEM);
                    200:        }
                    201:        isc->gatt = gatt;
                    202:
                    203:        gatt->ag_entries = AGP_GET_APERTURE(sc) >> AGP_PAGE_SHIFT;
                    204:
                    205:        if (isc->chiptype == CHIP_I810) {
                    206:                int dummyseg;
                    207:                /* Some i810s have on-chip memory called dcache */
                    208:                if (READ1(AGP_I810_DRT) & AGP_I810_DRT_POPULATED)
                    209:                        isc->dcache_size = 4 * 1024 * 1024;
                    210:                else
                    211:                        isc->dcache_size = 0;
                    212:
                    213:                /* According to the specs the gatt on the i810 must be 64k */
                    214:                if (agp_alloc_dmamem(sc->sc_dmat, 64 * 1024,
                    215:                    0, &gatt->ag_dmamap, (caddr_t *)&gatt->ag_virtual,
                    216:                    &gatt->ag_physical, &gatt->ag_dmaseg, 1, &dummyseg) != 0) {
                    217:                        free(gatt, M_DEVBUF);
                    218:                        agp_generic_detach(sc);
                    219:                        return (ENOMEM);
                    220:                }
                    221:
                    222:                gatt->ag_size = gatt->ag_entries * sizeof(u_int32_t);
                    223:                memset(gatt->ag_virtual, 0, gatt->ag_size);
                    224:
                    225:                agp_flush_cache();
                    226:                /* Install the GATT. */
                    227:                WRITE4(AGP_I810_PGTBL_CTL, gatt->ag_physical | 1);
                    228:        } else if (isc->chiptype == CHIP_I830) {
                    229:                /* The i830 automatically initializes the 128k gatt on boot. */
                    230:                pcireg_t reg;
                    231:                u_int32_t pgtblctl;
                    232:                u_int16_t gcc1;
                    233:
                    234:                reg = pci_conf_read(isc->bridge_pa.pa_pc,
                    235:                    isc->bridge_pa.pa_tag, AGP_I830_GCC1);
                    236:                gcc1 = (u_int16_t)(reg >> 16);
                    237:                switch (gcc1 & AGP_I830_GCC1_GMS) {
                    238:                case AGP_I830_GCC1_GMS_STOLEN_512:
                    239:                        isc->stolen = (512 - 132) * 1024 / 4096;
                    240:                        break;
                    241:                case AGP_I830_GCC1_GMS_STOLEN_1024:
                    242:                        isc->stolen = (1024 - 132) * 1024 / 4096;
                    243:                        break;
                    244:                case AGP_I830_GCC1_GMS_STOLEN_8192:
                    245:                        isc->stolen = (8192 - 132) * 1024 / 4096;
                    246:                        break;
                    247:                default:
                    248:                        isc->stolen = 0;
                    249:                        printf(
                    250:                            ": unknown memory configuration, disabling\n");
                    251:                        agp_generic_detach(sc);
                    252:                        return (EINVAL);
                    253:                }
                    254: #ifdef DEBUG
                    255:                if (isc->stolen > 0) {
                    256:                        printf(": detected %dk stolen memory",
                    257:                            isc->stolen * 4);
                    258:                }
                    259: #endif
                    260:
                    261:                /* GATT address is already in there, make sure it's enabled */
                    262:                pgtblctl = READ4(AGP_I810_PGTBL_CTL);
                    263:                pgtblctl |= 1;
                    264:                WRITE4(AGP_I810_PGTBL_CTL, pgtblctl);
                    265:
                    266:                gatt->ag_physical = pgtblctl & ~1;
                    267:        } else if (isc->chiptype == CHIP_I915) {
                    268:                /* The 915G automatically initializes the 256k gatt on boot. */
                    269:                pcireg_t reg;
                    270:                u_int32_t pgtblctl;
                    271:                u_int16_t gcc1;
                    272:
                    273:                reg = pci_conf_read(isc->bridge_pa.pa_pc,
                    274:                    isc->bridge_pa.pa_tag, AGP_I855_GCC1);
                    275:                gcc1 = (u_int16_t)(reg >> 16);
                    276:                switch (gcc1 & AGP_I855_GCC1_GMS) {
                    277:                case AGP_I855_GCC1_GMS_STOLEN_1M:
                    278:                        isc->stolen = (1024 - 260) * 1024 / 4096;
                    279:                        break;
                    280:                case AGP_I855_GCC1_GMS_STOLEN_4M:
                    281:                        isc->stolen = (4096 - 260) * 1024 / 4096;
                    282:                        break;
                    283:                case AGP_I855_GCC1_GMS_STOLEN_8M:
                    284:                        isc->stolen = (8192 - 260) * 1024 / 4096;
                    285:                        break;
                    286:                case AGP_I855_GCC1_GMS_STOLEN_16M:
                    287:                        isc->stolen = (16384 - 260) * 1024 / 4096;
                    288:                        break;
                    289:                case AGP_I855_GCC1_GMS_STOLEN_32M:
                    290:                        isc->stolen = (32768 - 260) * 1024 / 4096;
                    291:                        break;
                    292:                case AGP_I915_GCC1_GMS_STOLEN_48M:
                    293:                        isc->stolen = (49152 - 260) * 1024 / 4096;
                    294:                        break;
                    295:                case AGP_I915_GCC1_GMS_STOLEN_64M:
                    296:                        isc->stolen = (65536 - 260) * 1024 / 4096;
                    297:                        break;
                    298:                default:
                    299:                        isc->stolen = 0;
                    300:                        printf(
                    301:                            ": unknown memory configuration, disabling\n");
                    302:                        agp_generic_detach(sc);
                    303:                        return (EINVAL);
                    304:                }
                    305: #ifdef DEBUG
                    306:                if (isc->stolen > 0) {
                    307:                        printf(": detected %dk stolen memory",
                    308:                            isc->stolen * 4);
                    309:                }
                    310: #endif
                    311:
                    312:                /* GATT address is already in there, make sure it's enabled */
                    313:                pgtblctl = READ4(AGP_I810_PGTBL_CTL);
                    314:                pgtblctl |= 1;
                    315:                WRITE4(AGP_I810_PGTBL_CTL, pgtblctl);
                    316:
                    317:                gatt->ag_physical = pgtblctl & ~1;
                    318:        } else if (isc->chiptype == CHIP_I965) {
                    319:                pcireg_t reg;
                    320:                u_int32_t pgtblctl;
                    321:                u_int16_t gcc1;
                    322:                u_int32_t gttsize;
                    323:
                    324:                switch (READ4(AGP_I810_PGTBL_CTL) &
                    325:                    AGP_I810_PGTBL_SIZE_MASK) {
                    326:                case AGP_I810_PGTBL_SIZE_512KB:
                    327:                        gttsize = 512 + 4;
                    328:                        break;
                    329:                case AGP_I810_PGTBL_SIZE_256KB:
                    330:                        gttsize = 256 + 4;
                    331:                        break;
                    332:                case AGP_I810_PGTBL_SIZE_128KB:
                    333:                default:
                    334:                        gttsize = 128 + 4;
                    335:                        break;
                    336:                }
                    337:
                    338:                reg = pci_conf_read(isc->bridge_pa.pa_pc,
                    339:                    isc->bridge_pa.pa_tag, AGP_I855_GCC1);
                    340:                gcc1 = (u_int16_t)(reg >> 16);
                    341:                switch (gcc1 & AGP_I855_GCC1_GMS) {
                    342:                case AGP_I855_GCC1_GMS_STOLEN_1M:
                    343:                        isc->stolen = (1024 - gttsize) * 1024 / 4096;
                    344:                        break;
                    345:                case AGP_I855_GCC1_GMS_STOLEN_4M:
                    346:                        isc->stolen = (4096 - gttsize) * 1024 / 4096;
                    347:                        break;
                    348:                case AGP_I855_GCC1_GMS_STOLEN_8M:
                    349:                        isc->stolen = (8192 - gttsize) * 1024 / 4096;
                    350:                        break;
                    351:                case AGP_I855_GCC1_GMS_STOLEN_16M:
                    352:                        isc->stolen = (16384 - gttsize) * 1024 / 4096;
                    353:                        break;
                    354:                case AGP_I855_GCC1_GMS_STOLEN_32M:
                    355:                        isc->stolen = (32768 - gttsize) * 1024 / 4096;
                    356:                        break;
                    357:                case AGP_I915_GCC1_GMS_STOLEN_48M:
                    358:                        isc->stolen = (49152 - gttsize) * 1024 / 4096;
                    359:                        break;
                    360:                case AGP_I915_GCC1_GMS_STOLEN_64M:
                    361:                        isc->stolen = (65536 - gttsize) * 1024 / 4096;
                    362:                        break;
                    363:                case AGP_G33_GCC1_GMS_STOLEN_128M:
                    364:                        isc->stolen = (131072 - gttsize) * 1024 / 4096;
                    365:                        break;
                    366:                case AGP_G33_GCC1_GMS_STOLEN_256M:
                    367:                        isc->stolen = (262144 - gttsize) * 1024 / 4096;
                    368:                        break;
                    369:                default:
                    370:                        isc->stolen = 0;
                    371:                        printf(": unknown memory configuration 0x%x, "
                    372:                            "disabling\n", reg);
                    373:                        agp_generic_detach(sc);
                    374:                        return (EINVAL);
                    375:                }
                    376: #ifdef DEBUG
                    377:                if (isc->stolen > 0) {
                    378:                        printf(": detected %dk stolen memory",
                    379:                            isc->stolen * 4);
                    380:                }
                    381: #endif
                    382:
                    383:                /* GATT address is already in there, make sure it's enabled */
                    384:                pgtblctl = READ4(AGP_I810_PGTBL_CTL);
                    385:                pgtblctl |= 1;
                    386:                WRITE4(AGP_I810_PGTBL_CTL, pgtblctl);
                    387:
                    388:                gatt->ag_physical = pgtblctl & ~1;
                    389:        } else {        /* CHIP_I855 */
                    390:                /* The 855GM automatically initializes the 128k gatt on boot. */
                    391:                pcireg_t reg;
                    392:                u_int32_t pgtblctl;
                    393:                u_int16_t gcc1;
                    394:
                    395:                reg = pci_conf_read(isc->bridge_pa.pa_pc,
                    396:                    isc->bridge_pa.pa_tag, AGP_I855_GCC1);
                    397:                gcc1 = (u_int16_t)(reg >> 16);
                    398:                switch (gcc1 & AGP_I855_GCC1_GMS) {
                    399:                case AGP_I855_GCC1_GMS_STOLEN_1M:
                    400:                        isc->stolen = (1024 - 132) * 1024 / 4096;
                    401:                        break;
                    402:                case AGP_I855_GCC1_GMS_STOLEN_4M:
                    403:                        isc->stolen = (4096 - 132) * 1024 / 4096;
                    404:                        break;
                    405:                case AGP_I855_GCC1_GMS_STOLEN_8M:
                    406:                        isc->stolen = (8192 - 132) * 1024 / 4096;
                    407:                        break;
                    408:                case AGP_I855_GCC1_GMS_STOLEN_16M:
                    409:                        isc->stolen = (16384 - 132) * 1024 / 4096;
                    410:                        break;
                    411:                case AGP_I855_GCC1_GMS_STOLEN_32M:
                    412:                        isc->stolen = (32768 - 132) * 1024 / 4096;
                    413:                        break;
                    414:                default:
                    415:                        isc->stolen = 0;
                    416:                        printf(
                    417:                            ": unknown memory configuration, disabling\n");
                    418:                        agp_generic_detach(sc);
                    419:                        return (EINVAL);
                    420:                }
                    421: #ifdef DEBUG
                    422:                if (isc->stolen > 0) {
                    423:                        printf(": detected %dk stolen memory",
                    424:                            isc->stolen * 4);
                    425:                }
                    426: #endif
                    427:
                    428:                /* GATT address is already in there, make sure it's enabled */
                    429:                pgtblctl = READ4(AGP_I810_PGTBL_CTL);
                    430:                pgtblctl |= 1;
                    431:                WRITE4(AGP_I810_PGTBL_CTL, pgtblctl);
                    432:
                    433:                gatt->ag_physical = pgtblctl & ~1;
                    434:        }
                    435:
                    436:        /*
                    437:         * Make sure the chipset can see everything.
                    438:         */
                    439:        agp_flush_cache();
                    440:
                    441:        return (0);
                    442: }
                    443:
                    444: u_int32_t
                    445: agp_i810_get_aperture(struct vga_pci_softc *sc)
                    446: {
                    447:        struct agp_i810_softc *isc = sc->sc_chipc;
                    448:        pcireg_t reg;
                    449:
                    450:        if (isc->chiptype == CHIP_I810) {
                    451:                u_int16_t miscc;
                    452:
                    453:                reg = pci_conf_read(isc->bridge_pa.pa_pc,
                    454:                    isc->bridge_pa.pa_tag, AGP_I810_SMRAM);
                    455:                miscc = (u_int16_t)(reg >> 16);
                    456:                if ((miscc & AGP_I810_MISCC_WINSIZE) ==
                    457:                    AGP_I810_MISCC_WINSIZE_32)
                    458:                        return (32 * 1024 * 1024);
                    459:                else
                    460:                        return (64 * 1024 * 1024);
                    461:        } else if (isc->chiptype == CHIP_I830) {
                    462:                u_int16_t gcc1;
                    463:
                    464:                reg = pci_conf_read(isc->bridge_pa.pa_pc,
                    465:                    isc->bridge_pa.pa_tag, AGP_I830_GCC0);
                    466:                gcc1 = (u_int16_t)(reg >> 16);
                    467:                if ((gcc1 & AGP_I830_GCC1_GMASIZE) == AGP_I830_GCC1_GMASIZE_64)
                    468:                        return (64 * 1024 * 1024);
                    469:                else
                    470:                        return (128 * 1024 * 1024);
                    471:        } else if (isc->chiptype == CHIP_I915) {
                    472:                reg = pci_conf_read(isc->bridge_pa.pa_pc,
                    473:                    isc->bridge_pa.pa_tag, AGP_I915_MSAC);
                    474:                if ((reg & AGP_I915_MSAC_GMASIZE) == AGP_I915_MSAC_GMASIZE_128) {
                    475:                        return (128 * 1024 * 1024);
                    476:                } else {
                    477:                        return (256 * 1024 * 1024);
                    478:                }
                    479:        } else if (isc->chiptype == CHIP_I965) {
                    480:                reg = pci_conf_read(isc->bridge_pa.pa_pc,
                    481:                    isc->bridge_pa.pa_tag, AGP_I965_MSAC);
                    482:                switch (reg & AGP_I965_MSAC_GMASIZE) {
                    483:                case AGP_I965_MSAC_GMASIZE_128:
                    484:                        return (128 * 1024 * 1024);
                    485:                case AGP_I965_MSAC_GMASIZE_256:
                    486:                        return (256 * 1024 * 1024);
                    487:                case AGP_I965_MSAC_GMASIZE_512:
                    488:                        return (512 * 1024 * 1024);
                    489:                }
                    490:        }
                    491:
                    492:        /* CHIP_I855 */
                    493:        return (128 * 1024 * 1024);
                    494: }
                    495:
                    496: int
                    497: agp_i810_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
                    498: {
                    499:        struct agp_i810_softc *isc = sc->sc_chipc;
                    500:        pcireg_t reg;
                    501:
                    502:        if (isc->chiptype == CHIP_I810) {
                    503:                u_int16_t miscc;
                    504:
                    505:                /*
                    506:                 * Double check for sanity.
                    507:                 */
                    508:                if (aperture != (32 * 1024 * 1024) &&
                    509:                    aperture != (64 * 1024 * 1024)) {
                    510:                        printf("agp: bad aperture size %d\n", aperture);
                    511:                        return (EINVAL);
                    512:                }
                    513:
                    514:                reg = pci_conf_read(isc->bridge_pa.pa_pc,
                    515:                    isc->bridge_pa.pa_tag, AGP_I810_SMRAM);
                    516:                miscc = (u_int16_t)(reg >> 16);
                    517:                miscc &= ~AGP_I810_MISCC_WINSIZE;
                    518:                if (aperture == 32 * 1024 * 1024)
                    519:                        miscc |= AGP_I810_MISCC_WINSIZE_32;
                    520:                else
                    521:                        miscc |= AGP_I810_MISCC_WINSIZE_64;
                    522:
                    523:                reg &= 0x0000ffff;
                    524:                reg |= ((pcireg_t)miscc) << 16;
                    525:                pci_conf_write(isc->bridge_pa.pa_pc,
                    526:                    isc->bridge_pa.pa_tag, AGP_I810_SMRAM, reg);
                    527:        } else if (isc->chiptype == CHIP_I830) {
                    528:                u_int16_t gcc1;
                    529:
                    530:                if (aperture != (64 * 1024 * 1024) &&
                    531:                    aperture != (128 * 1024 * 1024)) {
                    532:                        printf("agp: bad aperture size %d\n", aperture);
                    533:                        return (EINVAL);
                    534:                }
                    535:                reg = pci_conf_read(isc->bridge_pa.pa_pc,
                    536:                    isc->bridge_pa.pa_tag, AGP_I830_GCC0);
                    537:                gcc1 = (u_int16_t)(reg >> 16);
                    538:                gcc1 &= ~AGP_I830_GCC1_GMASIZE;
                    539:                if (aperture == 64 * 1024 * 1024)
                    540:                        gcc1 |= AGP_I830_GCC1_GMASIZE_64;
                    541:                else
                    542:                        gcc1 |= AGP_I830_GCC1_GMASIZE_128;
                    543:
                    544:                reg &= 0x0000ffff;
                    545:                reg |= ((pcireg_t)gcc1) << 16;
                    546:                pci_conf_write(isc->bridge_pa.pa_pc,
                    547:                    isc->bridge_pa.pa_tag, AGP_I830_GCC0, reg);
                    548:        } else if (isc->chiptype == CHIP_I915) {
                    549:                if (aperture != (128 * 1024 * 1024) &&
                    550:                    aperture != (256 * 1024 * 1024)) {
                    551:                        printf("agp: bad aperture size %d\n", aperture);
                    552:                        return (EINVAL);
                    553:                }
                    554:                reg = pci_conf_read(isc->bridge_pa.pa_pc,
                    555:                    isc->bridge_pa.pa_tag, AGP_I915_MSAC);
                    556:                reg &= ~AGP_I915_MSAC_GMASIZE;
                    557:                if (aperture == (128 * 1024 * 1024))
                    558:                        reg |= AGP_I915_MSAC_GMASIZE_128;
                    559:                else
                    560:                        reg |= AGP_I915_MSAC_GMASIZE_256;
                    561:                pci_conf_write(isc->bridge_pa.pa_pc,
                    562:                    isc->bridge_pa.pa_tag, AGP_I915_MSAC, reg);
                    563:        } else if (isc->chiptype == CHIP_I965) {
                    564:                reg = pci_conf_read(isc->bridge_pa.pa_pc,
                    565:                    isc->bridge_pa.pa_tag, AGP_I965_MSAC);
                    566:                reg &= ~AGP_I965_MSAC_GMASIZE;
                    567:                switch (aperture) {
                    568:                case (128 * 1024 * 1024):
                    569:                        reg |= AGP_I965_MSAC_GMASIZE_128;
                    570:                        break;
                    571:                case (256 * 1024 * 1024):
                    572:                        reg |= AGP_I965_MSAC_GMASIZE_256;
                    573:                        break;
                    574:                case (512 * 1024 * 1024):
                    575:                        reg |= AGP_I965_MSAC_GMASIZE_512;
                    576:                        break;
                    577:                default:
                    578:                        printf("agp: bad aperture size %d\n", aperture);
                    579:                        return (EINVAL);
                    580:                }
                    581:                pci_conf_write(isc->bridge_pa.pa_pc,
                    582:                    isc->bridge_pa.pa_tag, AGP_I965_MSAC, reg);
                    583:        } else {        /* CHIP_I855 */
                    584:                if (aperture != (128 * 1024 * 1024)) {
                    585:                        printf("agp: bad aperture size %d\n", aperture);
                    586:                        return (EINVAL);
                    587:                }
                    588:        }
                    589:
                    590:        return (0);
                    591: }
                    592:
                    593: int
                    594: agp_i810_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
                    595: {
                    596:        struct agp_i810_softc *isc = sc->sc_chipc;
                    597:
                    598:        if (offset < 0 || offset >= (isc->gatt->ag_entries << AGP_PAGE_SHIFT)) {
                    599: #ifdef DEBUG
                    600:                printf("agp: failed: offset 0x%08x, shift %d, entries %d\n",
                    601:                    (int)offset, AGP_PAGE_SHIFT,
                    602:                    isc->gatt->ag_entries);
                    603: #endif
                    604:                return (EINVAL);
                    605:        }
                    606:
                    607:        if (isc->chiptype != CHIP_I810) {
                    608:                if ((offset >> AGP_PAGE_SHIFT) < isc->stolen) {
                    609: #ifdef DEBUG
                    610:                        printf("agp: trying to bind into stolen memory\n");
                    611: #endif
                    612:                        return (EINVAL);
                    613:                }
                    614:        }
                    615:
                    616:        WRITE_GATT(offset, physical);
                    617:        return (0);
                    618: }
                    619:
                    620: int
                    621: agp_i810_unbind_page(struct vga_pci_softc *sc, off_t offset)
                    622: {
                    623:        struct agp_i810_softc *isc = sc->sc_chipc;
                    624:
                    625:        if (offset < 0 || offset >= (isc->gatt->ag_entries << AGP_PAGE_SHIFT))
                    626:                return (EINVAL);
                    627:
                    628:        if (isc->chiptype != CHIP_I810 ) {
                    629:                if ((offset >> AGP_PAGE_SHIFT) < isc->stolen) {
                    630: #ifdef DEBUG
                    631:                        printf("agp: trying to unbind from stolen memory\n");
                    632: #endif
                    633:                        return (EINVAL);
                    634:                }
                    635:        }
                    636:
                    637:        WRITE_GATT(offset, 0);
                    638:        return (0);
                    639: }
                    640:
                    641: /*
                    642:  * Writing via memory mapped registers already flushes all TLBs.
                    643:  */
                    644: void
                    645: agp_i810_flush_tlb(struct vga_pci_softc *sc)
                    646: {
                    647: }
                    648:
                    649: int
                    650: agp_i810_enable(struct vga_pci_softc *sc, u_int32_t mode)
                    651: {
                    652:        return (0);
                    653: }
                    654:
                    655: struct agp_memory *
                    656: agp_i810_alloc_memory(struct vga_pci_softc *sc, int type, vsize_t size)
                    657: {
                    658:        struct agp_i810_softc *isc = sc->sc_chipc;
                    659:        struct agp_memory *mem;
                    660:        int error;
                    661:
                    662:        if ((size & (AGP_PAGE_SIZE - 1)) != 0)
                    663:                return 0;
                    664:
                    665:        if (type == 1) {
                    666:                /*
                    667:                 * Mapping local DRAM into GATT.
                    668:                 */
                    669:                if (isc->chiptype != CHIP_I810 )
                    670:                        return (NULL);
                    671:                if (size != isc->dcache_size)
                    672:                        return (NULL);
                    673:        } else if (type == 2) {
                    674:                /*
                    675:                 * Bogus mapping of 1 or 4 pages for the hardware cursor.
                    676:                 */
                    677:                if (size != AGP_PAGE_SIZE && size != 4 * AGP_PAGE_SIZE) {
                    678:                        printf("agp: trying to map %lu for hw cursor\n", size);
                    679:                        return (NULL);
                    680:                }
                    681:        }
                    682:
                    683:        mem = malloc(sizeof *mem, M_DEVBUF, M_WAITOK);
                    684:        bzero(mem, sizeof *mem);
                    685:        mem->am_id = sc->sc_nextid++;
                    686:        mem->am_size = size;
                    687:        mem->am_type = type;
                    688:
                    689:        if (type == 2) {
                    690:                /*
                    691:                 * Allocate and wire down the pages now so that we can
                    692:                 * get their physical address.
                    693:                 */
                    694:                mem->am_dmaseg = malloc(sizeof *mem->am_dmaseg, M_DEVBUF,
                    695:                    M_WAITOK);
                    696:                if (mem->am_dmaseg == NULL) {
                    697:                        free(mem, M_DEVBUF);
                    698:                        return (NULL);
                    699:                }
                    700:                if ((error = agp_alloc_dmamem(sc->sc_dmat, size, 0,
                    701:                    &mem->am_dmamap, &mem->am_virtual, &mem->am_physical,
                    702:                    mem->am_dmaseg, 1, &mem->am_nseg)) != 0) {
                    703:                        free(mem->am_dmaseg, M_DEVBUF);
                    704:                        free(mem, M_DEVBUF);
                    705:                        printf("agp: agp_alloc_dmamem(%d)\n", error);
                    706:                        return (NULL);
                    707:                }
                    708:        } else if (type != 1) {
                    709:                if ((error = bus_dmamap_create(sc->sc_dmat, size,
                    710:                    size / PAGE_SIZE + 1, size, 0, BUS_DMA_NOWAIT,
                    711:                    &mem->am_dmamap)) != 0) {
                    712:                        free(mem, M_DEVBUF);
                    713:                        printf("agp: bus_dmamap_create(%d)\n", error);
                    714:                        return (NULL);
                    715:                }
                    716:        }
                    717:
                    718:        TAILQ_INSERT_TAIL(&sc->sc_memory, mem, am_link);
                    719:        sc->sc_allocated += size;
                    720:
                    721:        return (mem);
                    722: }
                    723:
                    724: int
                    725: agp_i810_free_memory(struct vga_pci_softc *sc, struct agp_memory *mem)
                    726: {
                    727:        if (mem->am_is_bound)
                    728:                return (EBUSY);
                    729:
                    730:        if (mem->am_type == 2) {
                    731:                agp_free_dmamem(sc->sc_dmat, mem->am_size, mem->am_dmamap,
                    732:                    mem->am_virtual, mem->am_dmaseg, mem->am_nseg);
                    733:                free(mem->am_dmaseg, M_DEVBUF);
                    734:        }
                    735:
                    736:        sc->sc_allocated -= mem->am_size;
                    737:        TAILQ_REMOVE(&sc->sc_memory, mem, am_link);
                    738:        free(mem, M_DEVBUF);
                    739:        return (0);
                    740: }
                    741:
                    742: int
                    743: agp_i810_bind_memory(struct vga_pci_softc *sc, struct agp_memory *mem,
                    744:                     off_t offset)
                    745: {
                    746:        struct agp_i810_softc *isc = sc->sc_chipc;
                    747:        u_int32_t regval, i;
                    748:
                    749:        /*
                    750:         * XXX evil hack: the PGTBL_CTL appearently gets overwritten by the
                    751:         * X server for mysterious reasons which leads to crashes if we write
                    752:         * to the GTT through the MMIO window.
                    753:         * Until the issue is solved, simply restore it.
                    754:         */
                    755:        regval = bus_space_read_4(isc->bst, isc->bsh, AGP_I810_PGTBL_CTL);
                    756:        if (regval != (isc->gatt->ag_physical | 1)) {
                    757: #if DEBUG
                    758:                printf("agp_i810_bind_memory: PGTBL_CTL is 0x%x - fixing\n",
                    759:                    regval);
                    760: #endif
                    761:                bus_space_write_4(isc->bst, isc->bsh, AGP_I810_PGTBL_CTL,
                    762:                    isc->gatt->ag_physical | 1);
                    763:        }
                    764:
                    765:        if (mem->am_type == 2) {
                    766:                for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
                    767:                        WRITE_GATT(offset + i, mem->am_physical + i);
                    768:                }
                    769:                mem->am_offset = offset;
                    770:                mem->am_is_bound = 1;
                    771:                return (0);
                    772:        }
                    773:
                    774:        if (mem->am_type != 1)
                    775:                return (agp_generic_bind_memory(sc, mem, offset));
                    776:
                    777:        if (isc->chiptype != CHIP_I810)
                    778:                return (EINVAL);
                    779:
                    780:        for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
                    781:                WRITE4(AGP_I810_GTT +
                    782:                    (u_int32_t)(offset >> AGP_PAGE_SHIFT) * 4, i | 3);
                    783:        }
                    784:        mem->am_is_bound = 1;
                    785:        return (0);
                    786: }
                    787:
                    788: int
                    789: agp_i810_unbind_memory(struct vga_pci_softc *sc, struct agp_memory *mem)
                    790: {
                    791:        struct agp_i810_softc *isc = sc->sc_chipc;
                    792:        u_int32_t i;
                    793:
                    794:        if (mem->am_type == 2) {
                    795:                for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
                    796:                        WRITE_GATT(mem->am_offset + i, 0);
                    797:                }
                    798:                mem->am_offset = 0;
                    799:                mem->am_is_bound = 0;
                    800:                return (0);
                    801:        }
                    802:
                    803:        if (mem->am_type != 1)
                    804:                return (agp_generic_unbind_memory(sc, mem));
                    805:
                    806:        if (isc->chiptype != CHIP_I810)
                    807:                return (EINVAL);
                    808:
                    809:        for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
                    810:                WRITE4(AGP_I810_GTT + (i >> AGP_PAGE_SHIFT) * 4, 0);
                    811:        mem->am_is_bound = 0;
                    812:        return (0);
                    813: }
                    814:
                    815: void
                    816: agp_i810_write_gatt(struct agp_i810_softc *isc, bus_size_t off, u_int32_t v)
                    817: {
                    818:        u_int32_t d;
                    819:
                    820:
                    821:        d = v | 1;
                    822:
                    823:        if (isc->chiptype == CHIP_I915)
                    824:                WRITEGTT((u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, v ? d : 0);
                    825:        else if (isc->chiptype == CHIP_I965) {
                    826:                d |= (v & 0x0000000f00000000ULL) >> 28;
                    827:                WRITE4(AGP_I965_GTT +
                    828:                    (u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, v ? d : 0);
                    829:        } else
                    830:                WRITE4(AGP_I810_GTT +
                    831:                    (u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, v ? d : 0);
                    832: }

CVSweb