Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci Rework agp_i810 memory binding.



details:   https://anonhg.NetBSD.org/src/rev/ecec80f1ce3d
branches:  trunk
changeset: 329821:ecec80f1ce3d
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Tue Jun 10 22:02:58 2014 +0000

description:
Rework agp_i810 memory binding.

Principal reason is that the GTT size is not necessarily the same as
the aperture size: the GPU may have a bigger virtual address space
than the CPU can see through the aperture.

While here, factor the code a little more legibly and name some magic
constants.

diffstat:

 sys/dev/pci/agp_i810.c |  394 ++++++++++++++++++++++++++++++------------------
 1 files changed, 248 insertions(+), 146 deletions(-)

diffs (truncated from 512 to 300 lines):

diff -r 0c335999ca92 -r ecec80f1ce3d sys/dev/pci/agp_i810.c
--- a/sys/dev/pci/agp_i810.c    Tue Jun 10 22:01:40 2014 +0000
+++ b/sys/dev/pci/agp_i810.c    Tue Jun 10 22:02:58 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: agp_i810.c,v 1.85 2014/06/10 14:00:56 riastradh Exp $  */
+/*     $NetBSD: agp_i810.c,v 1.86 2014/06/10 22:02:58 riastradh Exp $  */
 
 /*-
  * Copyright (c) 2000 Doug Rabson
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.85 2014/06/10 14:00:56 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.86 2014/06/10 22:02:58 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -81,7 +81,14 @@
 static struct agp_memory *agp_i810_alloc_memory(struct agp_softc *, int,
                                                vsize_t);
 static int agp_i810_free_memory(struct agp_softc *, struct agp_memory *);
-static int agp_i810_bind_memory(struct agp_softc *, struct agp_memory *, off_t);
+static int agp_i810_bind_memory(struct agp_softc *, struct agp_memory *,
+               off_t);
+static int agp_i810_bind_memory_main(struct agp_softc *, struct agp_memory *,
+               off_t);
+static int agp_i810_bind_memory_dcache(struct agp_softc *, struct agp_memory *,
+               off_t);
+static int agp_i810_bind_memory_hwcursor(struct agp_softc *,
+               struct agp_memory *, off_t);
 static int agp_i810_unbind_memory(struct agp_softc *, struct agp_memory *);
 
 static bool agp_i810_resume(device_t, const pmf_qual_t *);
@@ -1033,73 +1040,11 @@
 }
 
 static int
-agp_i810_set_aperture(struct agp_softc *sc, u_int32_t aperture)
+agp_i810_set_aperture(struct agp_softc *sc __unused,
+    uint32_t aperture __unused)
 {
-       struct agp_i810_softc *isc = sc->as_chipc;
-       pcireg_t reg;
-       u_int16_t miscc, gcc1;
-
-       switch (isc->chiptype) {
-       case CHIP_I810:
-               /*
-                * Double check for sanity.
-                */
-               if (aperture != (32 * 1024 * 1024) &&
-                   aperture != (64 * 1024 * 1024)) {
-                       aprint_error_dev(sc->as_dev, "bad aperture size %d\n",
-                           aperture);
-                       return EINVAL;
-               }
-
-               reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I810_SMRAM);
-               miscc = (u_int16_t)(reg >> 16);
-               miscc &= ~AGP_I810_MISCC_WINSIZE;
-               if (aperture == 32 * 1024 * 1024)
-                       miscc |= AGP_I810_MISCC_WINSIZE_32;
-               else
-                       miscc |= AGP_I810_MISCC_WINSIZE_64;
 
-               reg &= 0x0000ffff;
-               reg |= ((pcireg_t)miscc) << 16;
-               pci_conf_write(sc->as_pc, sc->as_tag, AGP_I810_SMRAM, reg);
-               break;
-       case CHIP_I830:
-               if (aperture != (64 * 1024 * 1024) &&
-                   aperture != (128 * 1024 * 1024)) {
-                       aprint_error_dev(sc->as_dev, "bad aperture size %d\n",
-                           aperture);
-                       return EINVAL;
-               }
-               reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I830_GCC0);
-               gcc1 = (u_int16_t)(reg >> 16);
-               gcc1 &= ~AGP_I830_GCC1_GMASIZE;
-               if (aperture == 64 * 1024 * 1024)
-                       gcc1 |= AGP_I830_GCC1_GMASIZE_64;
-               else
-                       gcc1 |= AGP_I830_GCC1_GMASIZE_128;
-
-               reg &= 0x0000ffff;
-               reg |= ((pcireg_t)gcc1) << 16;
-               pci_conf_write(sc->as_pc, sc->as_tag, AGP_I830_GCC0, reg);
-               break;
-       case CHIP_I855:
-       case CHIP_I915:
-               if (aperture != agp_i810_get_aperture(sc)) {
-                       aprint_error_dev(sc->as_dev, "bad aperture size %d\n",
-                           aperture);
-                       return EINVAL;
-               }
-               break;
-       case CHIP_I965:
-               if (aperture != 512 * 1024 * 1024) {
-                       aprint_error_dev(sc->as_dev, "bad aperture size %d\n",
-                           aperture);
-                       return EINVAL;
-               }
-               break;
-       }
-
-       return 0;
+       return ENOSYS;
 }
 
 static int
@@ -1165,105 +1110,123 @@
        return 0;
 }
 
+#define        AGP_I810_MEMTYPE_MAIN           0
+#define        AGP_I810_MEMTYPE_DCACHE         1
+#define        AGP_I810_MEMTYPE_HWCURSOR       2
+
 static struct agp_memory *
 agp_i810_alloc_memory(struct agp_softc *sc, int type, vsize_t size)
 {
        struct agp_i810_softc *isc = sc->as_chipc;
        struct agp_memory *mem;
+       int error;
 
 #ifdef AGP_DEBUG
        printf("AGP: alloc(%d, 0x%x)\n", type, (int) size);
 #endif
 
+       if (size <= 0)
+               return NULL;
        if ((size & (AGP_PAGE_SIZE - 1)) != 0)
-               return 0;
-
+               return NULL;
        if (sc->as_allocated + size > sc->as_maxmem)
-               return 0;
-
-       if (type == 1) {
-               /*
-                * Mapping local DRAM into GATT.
-                */
-               if (isc->chiptype != CHIP_I810 )
-                       return 0;
+               return NULL;
+       switch (type) {
+       case AGP_I810_MEMTYPE_MAIN:
+               break;
+       case AGP_I810_MEMTYPE_DCACHE:
+               if (isc->chiptype != CHIP_I810)
+                       return NULL;
                if (size != isc->dcache_size)
-                       return 0;
-       } else if (type == 2) {
-               /*
-                * Bogus mapping for the hardware cursor.
-                */
-               if (size != AGP_PAGE_SIZE && size != 4 * AGP_PAGE_SIZE)
-                       return 0;
+                       return NULL;
+               break;
+       case AGP_I810_MEMTYPE_HWCURSOR:
+               if ((size != AGP_PAGE_SIZE) &&
+                   (size != AGP_PAGE_SIZE*4))
+                       return NULL;
+               break;
+       default:
+               return NULL;
        }
 
-       mem = malloc(sizeof *mem, M_AGP, M_WAITOK|M_ZERO);
+       mem = malloc(sizeof(*mem), M_AGP, M_WAITOK|M_ZERO);
        if (mem == NULL)
-               return NULL;
+               goto fail0;
        mem->am_id = sc->as_nextid++;
        mem->am_size = size;
        mem->am_type = type;
 
-       if (type == 2) {
-               /*
-                * Allocate and wire down the memory now so that we can
-                * get its physical address.
-                */
-               mem->am_dmaseg = malloc(sizeof *mem->am_dmaseg, M_AGP,
+       switch (type) {
+       case AGP_I810_MEMTYPE_MAIN:
+               error = bus_dmamap_create(sc->as_dmat, size,
+                   (size >> AGP_PAGE_SHIFT) + 1, size, 0, BUS_DMA_WAITOK,
+                   &mem->am_dmamap);
+               if (error)
+                       goto fail1;
+               break;
+       case AGP_I810_MEMTYPE_DCACHE:
+               break;
+       case AGP_I810_MEMTYPE_HWCURSOR:
+               mem->am_dmaseg = malloc(sizeof(*mem->am_dmaseg), M_AGP,
                    M_WAITOK);
-               if (mem->am_dmaseg == NULL) {
-                       free(mem, M_AGP);
-                       return NULL;
+               error = agp_alloc_dmamem(sc->as_dmat, size, 0, &mem->am_dmamap,
+                   &mem->am_virtual, &mem->am_physical, mem->am_dmaseg, 1,
+                   &mem->am_nseg);
+               if (error) {
+                       free(mem->am_dmaseg, M_AGP);
+                       goto fail1;
                }
-               if (agp_alloc_dmamem(sc->as_dmat, size, 0,
-                   &mem->am_dmamap, &mem->am_virtual, &mem->am_physical,
-                   mem->am_dmaseg, 1, &mem->am_nseg) != 0) {
-                       free(mem->am_dmaseg, M_AGP);
-                       free(mem, M_AGP);
-                       return NULL;
-               }
-               memset(mem->am_virtual, 0, size);
-       } else if (type != 1) {
-               if (bus_dmamap_create(sc->as_dmat, size, size / PAGE_SIZE + 1,
-                                     size, 0, BUS_DMA_NOWAIT,
-                                     &mem->am_dmamap) != 0) {
-                       free(mem, M_AGP);
-                       return NULL;
-               }
+               (void)memset(mem->am_virtual, 0, size);
+               break;
+       default:
+               panic("invalid agp memory type: %d", type);
        }
 
        TAILQ_INSERT_TAIL(&sc->as_memory, mem, am_link);
        sc->as_allocated += size;
 
        return mem;
+
+fail1: free(mem, M_AGP);
+fail0: return NULL;
 }
 
 static int
 agp_i810_free_memory(struct agp_softc *sc, struct agp_memory *mem)
 {
+
        if (mem->am_is_bound)
                return EBUSY;
 
-       if (mem->am_type == 2) {
+       switch (mem->am_type) {
+       case AGP_I810_MEMTYPE_MAIN:
+       case AGP_I810_MEMTYPE_DCACHE:
+               break;
+       case AGP_I810_MEMTYPE_HWCURSOR:
                agp_free_dmamem(sc->as_dmat, mem->am_size, mem->am_dmamap,
                    mem->am_virtual, mem->am_dmaseg, mem->am_nseg);
                free(mem->am_dmaseg, M_AGP);
+               break;
+       default:
+               panic("invalid agp i810 memory type: %d", mem->am_type);
        }
 
        sc->as_allocated -= mem->am_size;
        TAILQ_REMOVE(&sc->as_memory, mem, am_link);
        free(mem, M_AGP);
+
        return 0;
 }
 
 static int
 agp_i810_bind_memory(struct agp_softc *sc, struct agp_memory *mem,
-                    off_t offset)
+    off_t offset)
 {
        struct agp_i810_softc *isc = sc->as_chipc;
-       u_int32_t regval, i;
+       uint32_t pgtblctl;
+       int error;
 
-       if (mem->am_is_bound != 0)
+       if (mem->am_is_bound)
                return EINVAL;
 
        /*
@@ -1272,33 +1235,173 @@
         * to the GTT through the MMIO window.
         * Until the issue is solved, simply restore it.
         */
-       regval = bus_space_read_4(isc->bst, isc->bsh, AGP_I810_PGTBL_CTL);
-       if (regval != isc->pgtblctl) {
-               printf("agp_i810_bind_memory: PGTBL_CTL is 0x%x - fixing\n",
-                      regval);
+       pgtblctl = bus_space_read_4(isc->bst, isc->bsh, AGP_I810_PGTBL_CTL);
+       if (pgtblctl != isc->pgtblctl) {
+               printf("agp_i810_bind_memory: PGTBL_CTL is 0x%"PRIx32
+                   " - fixing\n", pgtblctl);
                bus_space_write_4(isc->bst, isc->bsh, AGP_I810_PGTBL_CTL,
                    isc->pgtblctl);
        }
 
-       if (mem->am_type == 2) {
-               for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)



Home | Main Index | Thread Index | Old Index