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/d7b7d8784b70
branches: trunk
changeset: 796582:d7b7d8784b70
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 e7b614d9b551 -r d7b7d8784b70 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