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 attachment code a little.



details:   https://anonhg.NetBSD.org/src/rev/2dd38107119a
branches:  trunk
changeset: 796251:2dd38107119a
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Tue May 27 03:17:33 2014 +0000

description:
Rework agp_i810 attachment code a little.

- Fix up error branches in agp_i810_attach.

- Use a separate bus space handle for the GTT, whether it is in a
separate BAR or a subregion of the MMIO device registers, so that

(a) agp_i810_write_gtt_entry and agp_i810_post_gtt_entry are easier to
follow, and

(b) we can map the GTT prefetchable eventually.

diffstat:

 sys/dev/pci/agp_i810.c    |  306 +++++++++++++++++++++++++--------------------
 sys/dev/pci/agp_i810var.h |   39 +++--
 2 files changed, 195 insertions(+), 150 deletions(-)

diffs (truncated from 490 to 300 lines):

diff -r a3d239b57125 -r 2dd38107119a sys/dev/pci/agp_i810.c
--- a/sys/dev/pci/agp_i810.c    Tue May 27 02:21:29 2014 +0000
+++ b/sys/dev/pci/agp_i810.c    Tue May 27 03:17:33 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: agp_i810.c,v 1.78 2014/05/26 19:15:39 riastradh Exp $  */
+/*     $NetBSD: agp_i810.c,v 1.79 2014/05/27 03:17:33 riastradh Exp $  */
 
 /*-
  * Copyright (c) 2000 Doug Rabson
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.78 2014/05/26 19:15:39 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.79 2014/05/27 03:17:33 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -88,6 +88,7 @@
 static int agp_i810_init(struct agp_softc *);
 
 static int agp_i810_setup_chipset_flush_page(struct agp_softc *);
+static void agp_i810_teardown_chipset_flush_page(struct agp_softc *);
 static int agp_i810_init(struct agp_softc *);
 
 static struct agp_methods agp_i810_methods = {
@@ -107,7 +108,6 @@
 agp_i810_write_gtt_entry(struct agp_i810_softc *isc, off_t off, bus_addr_t v)
 {
        u_int32_t pte;
-       bus_size_t base_off, wroff;
 
        /* Bits 11:4 (physical start address extension) should be zero. */
        if ((v & 0xff0) != 0)
@@ -132,58 +132,18 @@
                }
        }
 
-       base_off = 0;
-       wroff = (off >> AGP_PAGE_SHIFT) * 4;
+       bus_space_write_4(isc->gtt_bst, isc->gtt_bsh,
+           4*(off >> AGP_PAGE_SHIFT), pte);
 
-       switch (isc->chiptype) {
-       case CHIP_I810:
-       case CHIP_I830:
-       case CHIP_I855:
-               base_off = AGP_I810_GTT;
-               break;
-       case CHIP_I965:
-               base_off = AGP_I965_GTT;
-               break;
-       case CHIP_G4X:
-               base_off = AGP_G4X_GTT;
-               break;
-       case CHIP_I915:
-       case CHIP_G33:
-               bus_space_write_4(isc->gtt_bst, isc->gtt_bsh, wroff, pte);
-               return 0;
-       }
-
-       WRITE4(base_off + wroff, pte);
        return 0;
 }
 
 void
 agp_i810_post_gtt_entry(struct agp_i810_softc *isc, off_t off)
 {
-       bus_size_t base_off, wroff;
 
-       base_off = 0;
-       wroff = (off >> AGP_PAGE_SHIFT) * 4;
-
-       switch (isc->chiptype) {
-       case CHIP_I810:
-       case CHIP_I830:
-       case CHIP_I855:
-               base_off = AGP_I810_GTT;
-               break;
-       case CHIP_I965:
-               base_off = AGP_I965_GTT;
-               break;
-       case CHIP_G4X:
-               base_off = AGP_G4X_GTT;
-               break;
-       case CHIP_I915:
-       case CHIP_G33:
-               (void)bus_space_read_4(isc->gtt_bst, isc->gtt_bsh, wroff);
-               return;
-       }
-
-       (void)READ4(base_off + wroff);
+       (void)bus_space_read_4(isc->gtt_bst, isc->gtt_bsh,
+           4*(off >> AGP_PAGE_SHIFT));
 }
 
 static void
@@ -313,14 +273,17 @@
        struct agp_softc *sc = device_private(self);
        struct agp_i810_softc *isc;
        struct agp_gatt *gatt;
-       int error, apbase;
-       bus_addr_t mmadr;
-       bus_size_t mmadrsize;
+       int apbase, mmadr_bar, gtt_bar;
+       int mmadr_type, mmadr_flags;
+       bus_addr_t mmadr, gtt_off;
+       bus_size_t mmadr_size;
+       int error;
 
        isc = malloc(sizeof *isc, M_AGP, M_NOWAIT|M_ZERO);
        if (isc == NULL) {
                aprint_error(": can't allocate chipset-specific softc\n");
-               return ENOMEM;
+               error = ENOMEM;
+               goto fail0;
        }
        sc->as_chipc = isc;
        sc->as_methods = &agp_i810_methods;
@@ -335,12 +298,13 @@
                case PCI_PRODUCT_INTEL_82845G_DRAM:
                case PCI_PRODUCT_INTEL_82815_FULL_HUB:
                case PCI_PRODUCT_INTEL_82855GM_MCH:
+                       free(isc, M_AGP);
                        return agp_intel_attach(parent, self, aux);
                }
 #endif
                aprint_error(": can't find internal VGA device config space\n");
-               free(isc, M_AGP);
-               return ENOENT;
+               error = ENOENT;
+               goto fail1;
        }
 
        /* XXXfvdl */
@@ -405,90 +369,102 @@
                break;
        }
 
+       mmadr_type = PCI_MAPREG_TYPE_MEM;
        switch (isc->chiptype) {
        case CHIP_I915:
        case CHIP_G33:
                apbase = AGP_I915_GMADR;
+               mmadr_bar = AGP_I915_MMADR;
+               gtt_bar = AGP_I915_GTTADR;
                break;
        case CHIP_I965:
+               apbase = AGP_I965_GMADR;
+               mmadr_bar = AGP_I965_MMADR;
+               mmadr_type |= PCI_MAPREG_MEM_TYPE_64BIT;
+               gtt_bar = 0;
+               gtt_off = AGP_I965_GTT;
+               break;
        case CHIP_G4X:
                apbase = AGP_I965_GMADR;
+               mmadr_bar = AGP_I965_MMADR;
+               mmadr_type |= PCI_MAPREG_MEM_TYPE_64BIT;
+               gtt_bar = 0;
+               gtt_off = AGP_G4X_GTT;
                break;
        default:
                apbase = AGP_I810_GMADR;
+               mmadr_bar = AGP_I810_MMADR;
+               gtt_bar = 0;
+               gtt_off = AGP_I810_GTT;
                break;
        }
 
-       if (isc->chiptype == CHIP_I965 || isc->chiptype == CHIP_G4X) {
+       /* Map (or, rather, find the address and size of) the aperture.  */
+       if (isc->chiptype == CHIP_I965 || isc->chiptype == CHIP_G4X)
                error = agp_i965_map_aperture(&isc->vga_pa, sc, apbase);
-       } else {
+       else
                error = agp_map_aperture(&isc->vga_pa, sc, apbase);
-       }
-       if (error != 0) {
+       if (error) {
                aprint_error(": can't map aperture\n");
-               free(isc, M_AGP);
-               return error;
+               goto fail1;
        }
 
-       if (isc->chiptype == CHIP_I915 || isc->chiptype == CHIP_G33) {
-               error = pci_mapreg_map(&isc->vga_pa, AGP_I915_MMADR,
-                   PCI_MAPREG_TYPE_MEM, 0, &isc->bst, &isc->bsh,
-                   &mmadr, &mmadrsize);
-               if (error != 0) {
-                       aprint_error(": can't map mmadr registers\n");
-                       agp_generic_detach(sc);
-                       return error;
+       /* Map the memory-mapped I/O registers, or the non-GTT part.  */
+       if (pci_mapreg_info(isc->vga_pa.pa_pc, isc->vga_pa.pa_tag, mmadr_bar,
+               mmadr_type, &mmadr, &mmadr_size, &mmadr_flags)) {
+               aprint_error_dev(self, "can't find MMIO registers\n");
+               error = ENXIO;
+               goto fail1;
+       }
+       if (gtt_bar == 0) {
+               if (mmadr_size < gtt_off) {
+                       aprint_error_dev(self, "MMIO registers too small"
+                           ": %"PRIuMAX" < %"PRIuMAX"\n",
+                           (uintmax_t)mmadr_size, (uintmax_t)gtt_off);
+                       error = ENXIO;
+                       goto fail1;
                }
-               error = pci_mapreg_map(&isc->vga_pa, AGP_I915_GTTADR,
-                   PCI_MAPREG_TYPE_MEM, 0, &isc->gtt_bst, &isc->gtt_bsh,
-                   NULL, NULL);
-               if (error != 0) {
-                       aprint_error(": can't map gttadr registers\n");
-                       /* XXX we should release mmadr here */
-                       agp_generic_detach(sc);
-                       return error;
-               }
-       } else if (isc->chiptype == CHIP_I965 || isc->chiptype == CHIP_G4X) {
-               error = pci_mapreg_map(&isc->vga_pa, AGP_I965_MMADR,
-                   PCI_MAPREG_TYPE_MEM, 0, &isc->bst, &isc->bsh,
-                   &mmadr, &mmadrsize);
-               if (error != 0) {
-                       aprint_error(": can't map mmadr registers\n");
-                       agp_generic_detach(sc);
-                       return error;
+               isc->size = gtt_off;
+       } else {
+               isc->size = mmadr_size;
+       }
+       isc->bst = isc->vga_pa.pa_memt;
+       error = bus_space_map(isc->bst, mmadr, isc->size, mmadr_flags,
+           &isc->bsh);
+       if (error) {
+               aprint_error_dev(self, "can't map MMIO registers: %d\n",
+                   error);
+               error = ENXIO;
+               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, 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 {
-               error = pci_mapreg_map(&isc->vga_pa, AGP_I810_MMADR,
-                   PCI_MAPREG_TYPE_MEM, 0, &isc->bst, &isc->bsh,
-                   &mmadr, &mmadrsize);
-               if (error != 0) {
-                       aprint_error(": can't map mmadr registers\n");
-                       agp_generic_detach(sc);
-                       return error;
+               /*
+                * 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;
                }
        }
 
-       isc->initial_aperture = AGP_GET_APERTURE(sc);
-
-       gatt = malloc(sizeof(struct agp_gatt), M_AGP, M_NOWAIT);
-       if (!gatt) {
-               agp_generic_detach(sc);
-               return ENOMEM;
-       }
-       isc->gatt = gatt;
-
-       gatt->ag_entries = AGP_GET_APERTURE(sc) >> AGP_PAGE_SHIFT;
-
-       if (!pmf_device_register(self, NULL, agp_i810_resume))
-               aprint_error_dev(self, "couldn't establish power handler\n");
-
-       /*
-        * XXX horrible hack to allow drm code to use our mapping
-        * of VGA chip registers
-        */
-       agp_i810_vga_regbase = mmadr;
-       agp_i810_vga_bsh = isc->bsh;
-
        /* Set up a chipset flush page if necessary.  */
        switch (isc->chiptype) {
        case CHIP_I915:
@@ -500,13 +476,64 @@
                        aprint_error_dev(self,
                            "failed to set up chipset flush page: %d\n",



Home | Main Index | Thread Index | Old Index