Source-Changes-HG archive

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

[src/trunk]: src/sys AGP GART support code. Originally written by Doug Rabson...



details:   https://anonhg.NetBSD.org/src/rev/1e39f640c61d
branches:  trunk
changeset: 514754:1e39f640c61d
user:      fvdl <fvdl%NetBSD.org@localhost>
date:      Mon Sep 10 10:01:00 2001 +0000

description:
AGP GART support code. Originally written by Doug Rabson for FreeBSD,
modifications to fit it into the NetBSD device/config structure and
to use bus_dma by me.

diffstat:

 sys/dev/pci/agp.c       |  909 ++++++++++++++++++++++++++++++++++++++++++++++++
 sys/dev/pci/agp_ali.c   |  262 +++++++++++++
 sys/dev/pci/agp_amd.c   |  339 +++++++++++++++++
 sys/dev/pci/agp_i810.c  |  447 +++++++++++++++++++++++
 sys/dev/pci/agp_intel.c |  245 ++++++++++++
 sys/dev/pci/agp_sis.c   |  238 ++++++++++++
 sys/dev/pci/agp_via.c   |  231 ++++++++++++
 sys/dev/pci/agpreg.h    |  156 ++++++++
 sys/dev/pci/agpvar.h    |  270 ++++++++++++++
 sys/sys/agpio.h         |  130 ++++++
 10 files changed, 3227 insertions(+), 0 deletions(-)

diffs (truncated from 3267 to 300 lines):

diff -r b8cd49287a0d -r 1e39f640c61d sys/dev/pci/agp.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/pci/agp.c Mon Sep 10 10:01:00 2001 +0000
@@ -0,0 +1,909 @@
+/*     $NetBSD: agp.c,v 1.1 2001/09/10 10:01:01 fvdl Exp $     */
+
+/*-
+ * Copyright (c) 2000 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     $FreeBSD: src/sys/pci/agp.c,v 1.12 2001/05/19 01:28:07 alfred Exp $
+ */
+
+/*
+ * Copyright (c) 2001 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Frank van der Linden for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the NetBSD Project by
+ *      Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/conf.h>
+#include <sys/ioctl.h>
+#include <sys/fcntl.h>
+#include <sys/agpio.h>
+#include <sys/proc.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/agpvar.h>
+#include <dev/pci/agpreg.h>
+#include <dev/pci/pcidevs.h>
+
+#include <machine/bus.h>
+
+/* Helper functions for implementing chipset mini drivers. */
+/* XXXfvdl get rid of this one. */
+
+extern struct cfdriver agp_cd;
+cdev_decl(agp);
+
+int agpmatch(struct device *, struct cfdata *, void *);
+void agpattach(struct device *, struct device *, void *);
+
+struct cfattach agp_ca = {
+       sizeof(struct agp_softc), agpmatch, agpattach
+};
+
+static int agp_info_user(struct agp_softc *, agp_info *);
+static int agp_setup_user(struct agp_softc *, agp_setup *);
+static int agp_allocate_user(struct agp_softc *, agp_allocate *);
+static int agp_deallocate_user(struct agp_softc *, int);
+static int agp_bind_user(struct agp_softc *, agp_bind *);
+static int agp_unbind_user(struct agp_softc *, agp_unbind *);
+static int agpdev_match(struct pci_attach_args *);
+
+int
+agpmatch(struct device *parent, struct cfdata *match, void *aux)
+{
+       struct agp_phcb_attach_args *apa = aux;
+       struct pci_attach_args *pa = &apa->apa_pci_args;
+
+       switch (PCI_VENDOR(pa->pa_id)) {
+               case PCI_VENDOR_ALI:
+                       return agp_ali_match(parent, match, pa);
+               case PCI_VENDOR_AMD:
+                       return agp_amd_match(parent, match, pa);
+               case PCI_VENDOR_INTEL:
+                       if (agp_intel_match(parent, match, pa) != 0)
+                               return 1;
+                       return agp_i810_match(parent, match, pa);
+               case PCI_VENDOR_SIS:
+                       return agp_sis_match(parent, match, pa);
+               case PCI_VENDOR_VIATECH:
+                       return agp_via_match(parent, match, pa);
+               default:
+                       return 0;
+       }
+
+       return (0);
+}
+
+static int agp_max[][2] = {
+       {0,     0},
+       {32,    4},
+       {64,    28},
+       {128,   96},
+       {256,   204},
+       {512,   440},
+       {1024,  942},
+       {2048,  1920},
+       {4096,  3932}
+};
+#define agp_max_size   (sizeof(agp_max) / sizeof(agp_max[0]))
+
+void
+agpattach(struct device *parent, struct device *self, void *aux)
+{
+       struct agp_phcb_attach_args *apa = aux;
+       struct pci_attach_args *pa = &apa->apa_pci_args;
+       struct agp_softc *sc = (void *)self;
+       int memsize, i, ret;
+
+
+       sc->as_dmat = pa->pa_dmat;
+       sc->as_pc = pa->pa_pc;
+       sc->as_tag = pa->pa_tag;
+       sc->as_id = pa->pa_id;
+
+       /*
+        * Work out an upper bound for agp memory allocation. This
+        * uses a heurisitc table from the Linux driver.
+        */
+       memsize = ptoa(physmem) >> 20;
+       for (i = 0; i < agp_max_size; i++) {
+               if (memsize <= agp_max[i][0])
+                       break;
+       }
+       if (i == agp_max_size)
+               i = agp_max_size - 1;
+       sc->as_maxmem = agp_max[i][1] << 20U;
+
+       /*
+        * The lock is used to prevent re-entry to
+        * agp_generic_bind_memory() since that function can sleep.
+        */
+       lockinit(&sc->as_lock, PZERO|PCATCH, "agplk", 0, 0);
+
+       TAILQ_INIT(&sc->as_memory);
+
+       switch (PCI_VENDOR(pa->pa_id)) {
+               case PCI_VENDOR_ALI:
+                       ret = agp_ali_attach(parent, self, pa);
+                       break;
+               case PCI_VENDOR_AMD:
+                       ret = agp_amd_attach(parent, self, pa);
+                       break;
+               case PCI_VENDOR_INTEL:
+                       ret = agp_intel_attach(parent, self, pa);
+                       break;
+               case PCI_VENDOR_SIS:
+                       ret = agp_sis_attach(parent, self, pa);
+                       break;
+               case PCI_VENDOR_VIATECH:
+                       ret = agp_via_attach(parent, self, pa);
+                       break;
+               default:
+                       panic("agpattach: bad chipset detection");
+       }
+       if (ret == 0)
+               printf(": aperture at 0x%lx, size 0x%lx\n",
+                   (unsigned long)sc->as_apaddr,
+                   (unsigned long)AGP_GET_APERTURE(sc));
+       else
+               sc->as_chipc = NULL;
+}
+int
+agp_map_aperture(struct pci_attach_args *pa, struct agp_softc *sc)
+{
+       /*
+        * Find and map the aperture.
+        */
+       if (pci_mapreg_map(pa, AGP_APBASE, PCI_MAPREG_TYPE_MEM,
+           BUS_SPACE_MAP_LINEAR,
+           &sc->as_apt, &sc->as_aph, &sc->as_apaddr, &sc->as_apsize) != 0) {
+               printf("%s: can't map aperture space\n", sc->as_dev.dv_xname);
+               return ENXIO;
+       }
+       return 0;
+}
+
+struct agp_gatt *
+agp_alloc_gatt(struct agp_softc *sc)
+{
+       u_int32_t apsize = AGP_GET_APERTURE(sc);
+       u_int32_t entries = apsize >> AGP_PAGE_SHIFT;
+       struct agp_gatt *gatt;
+       int dummyseg;
+
+       gatt = malloc(sizeof(struct agp_gatt), M_AGP, M_NOWAIT);
+       if (!gatt)
+               return NULL;
+       gatt->ag_entries = entries;
+
+       if (agp_alloc_dmamem(sc->as_dmat, entries * sizeof(u_int32_t),
+           0, &gatt->ag_dmamap, (caddr_t *)&gatt->ag_virtual,
+           &gatt->ag_physical, &gatt->ag_dmaseg, 1, &dummyseg) != 0)
+               return NULL;
+
+       gatt->ag_size = entries * sizeof(u_int32_t);
+       memset(gatt->ag_virtual, 0, gatt->ag_size);
+       agp_flush_cache();
+
+       return gatt;
+}
+
+void
+agp_free_gatt(struct agp_softc *sc, struct agp_gatt *gatt)
+{
+       agp_free_dmamem(sc->as_dmat, gatt->ag_size, gatt->ag_dmamap,
+           (caddr_t)gatt->ag_virtual, &gatt->ag_dmaseg, 1);
+       free(gatt, M_AGP);
+}
+
+
+int
+agp_generic_detach(struct agp_softc *sc)
+{
+       lockmgr(&sc->as_lock, LK_DRAIN, 0);
+       agp_flush_cache();
+       return 0;
+}
+
+static int
+agpdev_match(struct pci_attach_args *pa)
+{
+       if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY &&
+           PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA)
+               return 1;
+
+       return 0;
+}
+
+int
+agp_generic_enable(struct agp_softc *sc, u_int32_t mode)
+{
+       struct pci_attach_args pa;
+       pcireg_t tstatus, mstatus;
+       pcireg_t command;
+       int rq, sba, fw, rate, capoff;
+
+       if (pci_find_device(&pa, agpdev_match) == 0 ||
+           pci_get_capability(pa.pa_pc, pa.pa_tag, PCI_CAP_AGP,
+            &capoff, NULL) == 0) {
+               printf("%s: can't find display\n", sc->as_dev.dv_xname);
+               return ENXIO;
+       }
+
+       tstatus = pci_conf_read(sc->as_pc, sc->as_tag,
+           sc->as_capoff + AGP_STATUS);
+       mstatus = pci_conf_read(pa.pa_pc, pa.pa_tag,
+           capoff + AGP_STATUS);
+
+       /* Set RQ to the min of mode, tstatus and mstatus */



Home | Main Index | Thread Index | Old Index