Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Another round of weed-whacking for agp_i810.
details: https://anonhg.NetBSD.org/src/rev/4e9749d50546
branches: trunk
changeset: 329804:4e9749d50546
user: riastradh <riastradh%NetBSD.org@localhost>
date: Tue Jun 10 14:00:56 2014 +0000
description:
Another round of weed-whacking for agp_i810.
- Make struct agp_i810_softc::gatt specific to i810 chipsets; use other
members of struct agp_i810_softc for non-i810 chipsets.
- agp_i810_init detects and sets isc->gtt_size.
- Map GTT based on the GTT size detected by agp_i810_init.
- Sprinkle some comments particularly about questionable calculations.
diffstat:
sys/dev/pci/agp_i810.c | 187 +++++++++++++++++++++++++--------------------
sys/dev/pci/agp_i810var.h | 16 ++-
2 files changed, 113 insertions(+), 90 deletions(-)
diffs (truncated from 419 to 300 lines):
diff -r c42f2e2ae639 -r 4e9749d50546 sys/dev/pci/agp_i810.c
--- a/sys/dev/pci/agp_i810.c Tue Jun 10 13:15:18 2014 +0000
+++ b/sys/dev/pci/agp_i810.c Tue Jun 10 14:00:56 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: agp_i810.c,v 1.84 2014/05/28 16:07:58 riastradh Exp $ */
+/* $NetBSD: agp_i810.c,v 1.85 2014/06/10 14:00:56 riastradh Exp $ */
/*-
* Copyright (c) 2000 Doug Rabson
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.84 2014/05/28 16:07:58 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.85 2014/06/10 14:00:56 riastradh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -272,7 +272,6 @@
{
struct agp_softc *sc = device_private(self);
struct agp_i810_softc *isc;
- struct agp_gatt *gatt;
int apbase, mmadr_bar, gtt_bar;
int mmadr_type, mmadr_flags;
bus_addr_t mmadr, gtt_off;
@@ -448,33 +447,6 @@
goto fail1;
}
- /* Map the GTT, from either part of the MMIO region or its own BAR. */
- if (gtt_bar == 0) {
- isc->gtt_bst = isc->bst;
- isc->gtt_size = (mmadr_size - gtt_off);
- error = bus_space_map(isc->gtt_bst, (mmadr + gtt_off),
- isc->gtt_size, mmadr_flags, &isc->gtt_bsh);
- if (error) {
- aprint_error_dev(self, "can't map GTT: %d\n", error);
- error = ENXIO;
- goto fail2;
- }
- } else {
- /*
- * All chipsets with a separate BAR for the GTT, namely
- * the i915 and G33 families, have 32-bit GTT BARs.
- *
- * XXX [citation needed]
- */
- if (pci_mapreg_map(&isc->vga_pa, gtt_bar, PCI_MAPREG_TYPE_MEM,
- 0,
- &isc->gtt_bst, &isc->gtt_bsh, NULL, &isc->gtt_size)) {
- aprint_error_dev(self, "can't map GTT\n");
- error = ENXIO;
- goto fail2;
- }
- }
-
/* Set up a chipset flush page if necessary. */
switch (isc->chiptype) {
case CHIP_I915:
@@ -485,25 +457,11 @@
if (error) {
aprint_error_dev(self,
"can't set up chipset flush page: %d\n", error);
- goto fail3;
+ goto fail2;
}
break;
}
- /* Set up the generic AGP GATT record. */
- isc->initial_aperture = AGP_GET_APERTURE(sc);
- gatt = malloc(sizeof(struct agp_gatt), M_AGP, M_NOWAIT);
- if (!gatt) {
- error = ENOMEM;
- goto fail4;
- }
- isc->gatt = gatt;
- gatt->ag_entries = AGP_GET_APERTURE(sc) >> AGP_PAGE_SHIFT;
-
- /* Power management. (XXX Nothing to save on suspend? Fishy...) */
- if (!pmf_device_register(self, NULL, agp_i810_resume))
- aprint_error_dev(self, "can't establish power handler\n");
-
/*
* XXX horrible hack to allow drm code to use our mapping
* of VGA chip registers
@@ -514,7 +472,56 @@
/* Initialize the chipset. */
error = agp_i810_init(sc);
if (error)
- goto fail5;
+ goto fail3;
+
+ /* Map the GTT, from either part of the MMIO region or its own BAR. */
+ if (gtt_bar == 0) {
+ isc->gtt_bst = isc->bst;
+ if (isc->gtt_size < (mmadr_size - gtt_off)) {
+ aprint_error_dev(self, "GTTMMADR too small for GTT"
+ ": %"PRIxMAX" < (%"PRIxMAX" - %"PRIxMAX")\n",
+ (uintmax_t)isc->gtt_size,
+ (uintmax_t)mmadr_size,
+ (uintmax_t)gtt_off);
+ error = ENXIO;
+ goto fail4;
+ }
+ error = bus_space_map(isc->gtt_bst, (mmadr + gtt_off),
+ isc->gtt_size, mmadr_flags, &isc->gtt_bsh);
+ if (error) {
+ aprint_error_dev(self, "can't map GTT: %d\n", error);
+ error = ENXIO;
+ goto fail4;
+ }
+ } else {
+ bus_size_t gtt_bar_size;
+ /*
+ * All chipsets with a separate BAR for the GTT, namely
+ * the i915 and G33 families, have 32-bit GTT BARs.
+ *
+ * XXX [citation needed]
+ */
+ if (pci_mapreg_map(&isc->vga_pa, gtt_bar, PCI_MAPREG_TYPE_MEM,
+ 0,
+ &isc->gtt_bst, &isc->gtt_bsh, NULL, >t_bar_size)) {
+ aprint_error_dev(self, "can't map GTT\n");
+ error = ENXIO;
+ goto fail4;
+ }
+ if (gtt_bar_size != isc->gtt_size) {
+ aprint_error_dev(self,
+ "BAR size %"PRIxMAX
+ " mismatches detected GTT size %"PRIxMAX
+ "; trusting BAR\n",
+ (uintmax_t)gtt_bar_size,
+ (uintmax_t)isc->gtt_size);
+ isc->gtt_size = gtt_bar_size;
+ }
+ }
+
+ /* Power management. (XXX Nothing to save on suspend? Fishy...) */
+ if (!pmf_device_register(self, NULL, agp_i810_resume))
+ aprint_error_dev(self, "can't establish power handler\n");
/* Match the generic AGP code's autoconf output format. */
aprint_normal("%s", device_xname(self));
@@ -522,14 +529,15 @@
/* Success! */
return 0;
+fail5: __unused
+ pmf_device_deregister(self);
+ bus_space_unmap(isc->gtt_bst, isc->gtt_bsh, isc->gtt_size);
+ isc->gtt_size = 0;
+fail4:
#if notyet
-fail6: __unused
agp_i810_fini(sc);
#endif
-fail5: pmf_device_deregister(self);
- free(gatt, M_AGP);
- isc->gatt = NULL;
-fail4: switch (isc->chiptype) {
+fail3: switch (isc->chiptype) {
case CHIP_I915:
case CHIP_I965:
case CHIP_G33:
@@ -537,8 +545,6 @@
agp_i810_teardown_chipset_flush_page(sc);
break;
}
-fail3: bus_space_unmap(isc->gtt_bst, isc->gtt_bsh, isc->gtt_size);
- isc->gtt_size = 0;
fail2: bus_space_unmap(isc->bst, isc->bsh, isc->size);
isc->size = 0;
fail1: free(isc, M_AGP);
@@ -667,13 +673,12 @@
agp_i810_init(struct agp_softc *sc)
{
struct agp_i810_softc *isc;
- struct agp_gatt *gatt;
int error;
isc = sc->as_chipc;
- gatt = isc->gatt;
if (isc->chiptype == CHIP_I810) {
+ struct agp_gatt *gatt;
void *virtual;
int dummyseg;
@@ -684,28 +689,42 @@
isc->dcache_size = 0;
/* According to the specs the gatt on the i810 must be 64k */
- error = agp_alloc_dmamem(sc->as_dmat, 64 * 1024,
+ isc->gtt_size = 64 * 1024;
+ gatt = malloc(sizeof(*gatt), M_AGP, M_NOWAIT);
+ if (gatt == NULL) {
+ aprint_error_dev(sc->as_dev,
+ "can't malloc GATT record\n");
+ error = ENOMEM;
+ goto fail0;
+ }
+ gatt->ag_entries = isc->gtt_size / sizeof(uint32_t);
+ error = agp_alloc_dmamem(sc->as_dmat, isc->gtt_size,
0, &gatt->ag_dmamap, &virtual, &gatt->ag_physical,
&gatt->ag_dmaseg, 1, &dummyseg);
if (error) {
aprint_error_dev(sc->as_dev,
"can't allocate memory for GTT: %d\n", error);
+ free(gatt, M_AGP);
goto fail0;
}
gatt->ag_virtual = (uint32_t *)virtual;
- gatt->ag_size = gatt->ag_entries * sizeof(u_int32_t);
+ gatt->ag_size = gatt->ag_entries * sizeof(uint32_t);
memset(gatt->ag_virtual, 0, gatt->ag_size);
+ agp_flush_cache();
- agp_flush_cache();
/* Install the GATT. */
- WRITE4(AGP_I810_PGTBL_CTL, gatt->ag_physical | 1);
+ isc->pgtblctl = gatt->ag_physical | 1;
+ WRITE4(AGP_I810_PGTBL_CTL, isc->pgtblctl);
+ isc->gatt = gatt;
} else if (isc->chiptype == CHIP_I830) {
/* The i830 automatically initializes the 128k gatt on boot. */
+ /* XXX [citation needed] */
pcireg_t reg;
- u_int32_t pgtblctl;
u_int16_t gcc1;
+ isc->gtt_size = 128 * 1024;
+
reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I830_GCC0);
gcc1 = (u_int16_t)(reg >> 16);
switch (gcc1 & AGP_I830_GCC1_GMS) {
@@ -733,22 +752,20 @@
}
/* GATT address is already in there, make sure it's enabled */
- pgtblctl = READ4(AGP_I810_PGTBL_CTL);
- pgtblctl |= 1;
- WRITE4(AGP_I810_PGTBL_CTL, pgtblctl);
-
- gatt->ag_physical = pgtblctl & ~1;
+ isc->pgtblctl = READ4(AGP_I810_PGTBL_CTL);
+ isc->pgtblctl |= 1;
+ WRITE4(AGP_I810_PGTBL_CTL, isc->pgtblctl);
} else if (isc->chiptype == CHIP_I855 || isc->chiptype == CHIP_I915 ||
isc->chiptype == CHIP_I965 || isc->chiptype == CHIP_G33 ||
isc->chiptype == CHIP_G4X) {
pcireg_t reg;
- u_int32_t pgtblctl, gtt_size, stolen;
+ u_int32_t gtt_size, stolen; /* XXX kilobytes */
u_int16_t gcc1;
reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I855_GCC1);
gcc1 = (u_int16_t)(reg >> 16);
- pgtblctl = READ4(AGP_I810_PGTBL_CTL);
+ isc->pgtblctl = READ4(AGP_I810_PGTBL_CTL);
/* Stolen memory is set up at the beginning of the aperture by
* the BIOS, consisting of the GATT followed by 4kb for the
@@ -762,7 +779,7 @@
gtt_size = 256;
break;
case CHIP_I965:
- switch (pgtblctl & AGP_I810_PGTBL_SIZE_MASK) {
+ switch (isc->pgtblctl & AGP_I810_PGTBL_SIZE_MASK) {
case AGP_I810_PGTBL_SIZE_128KB:
case AGP_I810_PGTBL_SIZE_512KB:
gtt_size = 512;
@@ -805,6 +822,10 @@
panic("impossible chiptype %d", isc->chiptype);
}
+ /*
+ * XXX If I'm reading the datasheets right, this stolen
+ * memory detection logic is totally wrong.
+ */
switch (gcc1 & AGP_I855_GCC1_GMS) {
case AGP_I855_GCC1_GMS_STOLEN_1M:
stolen = 1024;
@@ -878,9 +899,13 @@
break;
}
+ isc->gtt_size = gtt_size * 1024;
+
/* BIOS space */
+ /* XXX [citation needed] */
gtt_size += 4;
+ /* XXX [citation needed] for this subtraction */
isc->stolen = (stolen - gtt_size) * 1024 / 4096;
if (isc->stolen > 0) {
Home |
Main Index |
Thread Index |
Old Index