summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2007-11-25 17:11:13 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2007-11-25 17:11:13 +0000
commitf6e609402178409f4ffab378b534c5668d547e35 (patch)
tree01a30adae412455b8dc5fff7ffeb751f12ffbb93 /sys/dev/pci
parent36d2c964c15e49779643651e2e0f68f3a2b9f26c (diff)
Make agp attach as a device. This means that many more agp bridges
actually get detected and attached. Also adds a kernel api for manipulating agp. Enable this on i386 and amd64. "I think you should commit it" deraadt@, ok matthieu. Looked over by several others.
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/agp.c606
-rw-r--r--sys/dev/pci/agp_ali.c35
-rw-r--r--sys/dev/pci/agp_amd.c46
-rw-r--r--sys/dev/pci/agp_i810.c447
-rw-r--r--sys/dev/pci/agp_intel.c220
-rw-r--r--sys/dev/pci/agp_sis.c33
-rw-r--r--sys/dev/pci/agp_via.c115
-rw-r--r--sys/dev/pci/agpreg.h42
-rw-r--r--sys/dev/pci/agpvar.h222
-rw-r--r--sys/dev/pci/files.agp31
-rw-r--r--sys/dev/pci/files.pci3
-rw-r--r--sys/dev/pci/vga_pci.c24
-rw-r--r--sys/dev/pci/vga_pcivar.h65
13 files changed, 1218 insertions, 671 deletions
diff --git a/sys/dev/pci/agp.c b/sys/dev/pci/agp.c
index 52faa49e477..6c500c11bd2 100644
--- a/sys/dev/pci/agp.c
+++ b/sys/dev/pci/agp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: agp.c,v 1.7 2007/09/17 01:33:33 krw Exp $ */
+/* $OpenBSD: agp.c,v 1.8 2007/11/25 17:11:12 oga Exp $ */
/*-
* Copyright (c) 2000 Doug Rabson
* All rights reserved.
@@ -36,6 +36,7 @@
#include <uvm/uvm.h>
#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
#include <dev/ic/mc6845reg.h>
#include <dev/ic/pcdisplayvar.h>
@@ -45,17 +46,88 @@
#include <dev/pci/agpvar.h>
#include <dev/pci/agpreg.h>
-struct agp_memory *agp_find_memory(struct vga_pci_softc *sc, int id);
+#include "agp_ali.h"
+#include "agp_amd.h"
+#include "agp_amd64.h"
+#include "agp_apple.h"
+#include "agp_i810.h"
+#include "agp_intel.h"
+#include "agp_sis.h"
+#include "agp_via.h"
+
+struct agp_memory *agp_find_memory(struct agp_softc *sc, int id);
const struct agp_product *agp_lookup(struct pci_attach_args *pa);
+/* userland ioctl functions */
+static int agp_info_user(void *, agp_info *);
+static int agp_setup_user(void *, agp_setup *);
+static int agp_allocate_user(void *, agp_allocate *);
+static int agp_deallocate_user(void *, int);
+static int agp_bind_user(void *, agp_bind *);
+static int agp_unbind_user(void *, agp_unbind *);
+static int agp_acquire_helper(void *dev, enum agp_acquire_state state);
+static int agp_release_helper(void *dev, enum agp_acquire_state state);
+
+const struct agp_product agp_products[] = {
+#if NAGP_ALI > 0
+ { PCI_VENDOR_ALI, -1, agp_ali_attach },
+#endif
+#if NAGP_AMD > 0
+ { PCI_VENDOR_AMD, -1, agp_amd_attach },
+#endif
+#if NAGP_I810 > 0
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82810_MCH, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82810_DC100_MCH, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82810E_MCH, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82815_FULL_HUB, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82840_HB, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82830MP_IO_1, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82845G, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82852GM_HPB, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82865_IO_1, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82915G_HB, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82915GM_HB, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82945GP_MCH, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82945GM_MCH, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82Q963_HB, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82965_MCH, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82915G_IV, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82915GM_IGD, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82945G_IGD_1, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82945GM_IGD, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82965_IGD_1, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82965GM_IGD_1, agp_i810_attach },
+#endif
+#if NAGP_INTEL > 0
+ { PCI_VENDOR_INTEL, -1, agp_intel_attach },
+#endif
+#if NAGP_SIS > 0
+ { PCI_VENDOR_SIS, -1, agp_sis_attach },
+#endif
+#if NAGP_VIA > 0
+ { PCI_VENDOR_VIATECH, -1, agp_via_attach },
+#endif
+ { 0, 0, NULL }
+};
-struct pci_attach_args agp_pchb_pa;
-int agp_pchb_pa_set = 0;
+
+static int
+agp_probe(struct device *parent, void *match, void *aux)
+{
+ struct agpbus_attach_args *aaa = aux;
+ struct pci_attach_args *pa = &aaa->apa_pci_args;
+
+ if (agp_lookup(pa) == NULL)
+ return (0);
+
+ return (1);
+}
void
agp_attach(struct device *parent, struct device *self, void *aux)
{
- struct pci_attach_args *pa = aux;
- struct vga_pci_softc *sc = (struct vga_pci_softc *)self;
+ struct agpbus_attach_args *aaa = aux;
+ struct pci_attach_args *pa = &aaa->apa_pci_args;
+ struct agp_softc *sc = (struct agp_softc *)self;
const struct agp_product *ap;
u_int memsize;
int i, ret;
@@ -104,7 +176,7 @@ agp_attach(struct device *parent, struct device *self, void *aux)
pci_get_capability(sc->sc_pc, sc->sc_pcitag, PCI_CAP_AGP,
&sc->sc_capoff, NULL);
- ret = (*ap->ap_attach)(sc, pa, &agp_pchb_pa);
+ ret = (*ap->ap_attach)(sc, pa);
if (ret == 0)
printf(": aperture at 0x%lx, size 0x%lx",
(u_long)sc->sc_apaddr,
@@ -116,183 +188,123 @@ agp_attach(struct device *parent, struct device *self, void *aux)
}
}
+struct cfattach agp_ca = {
+ sizeof (struct agp_softc), agp_probe, agp_attach,
+ NULL, NULL
+};
+
+struct cfdriver agp_cd = {
+ NULL, "agp", DV_DULL
+};
+
paddr_t
-agp_mmap(void *v, off_t off, int prot)
+agpmmap(void *v, off_t off, int prot)
{
- struct vga_config* vs = (struct vga_config*) v;
- struct vga_pci_softc* sc = (struct vga_pci_softc *)vs->vc_softc;
+ struct agp_softc* sc = (struct agp_softc *)v;
if (sc->sc_apaddr) {
if (off > AGP_GET_APERTURE(sc))
return (-1);
+ /*
+ * XXX this should use bus_space_mmap() but it's not
+ * availiable on all archs.
+ */
return atop(sc->sc_apaddr + off);
}
- return -1;
+ return (-1);
}
+int agpopen(dev_t dev , int oflags, int devtype, struct proc * p)
+{
+ struct agp_softc *sc = (struct agp_softc *)device_lookup(&agp_cd, AGPUNIT(dev));
+
+ if (sc == NULL)
+ return (ENXIO);
+
+ if (sc->sc_chipc == NULL)
+ return (ENXIO);
+
+ if (!sc->sc_opened)
+ sc->sc_opened = 1;
+ else
+ return (EBUSY);
+
+ return (0);
+}
+
+
int
-agp_ioctl(void *v, u_long cmd, caddr_t addr, int flag, struct proc *pb)
+agpioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *pb)
{
- struct vga_config *vc = v;
- struct vga_pci_softc *sc = (struct vga_pci_softc *)vc->vc_softc;
- struct agp_memory *mem;
- agp_info *info;
- agp_setup *setup;
- agp_allocate *alloc;
- agp_bind *bind;
- agp_unbind *unbind;
- vsize_t size;
- int error = 0;
+ struct agp_softc *sc = (struct agp_softc *)device_lookup(&agp_cd, AGPUNIT(dev));
+
+ if (sc ==NULL)
+ return (ENODEV);
if (sc->sc_methods == NULL || sc->sc_chipc == NULL)
return (ENXIO);
+
+ if (cmd != AGPIOC_INFO && !(flag & FWRITE))
+ return (EPERM);
- switch (cmd) {
- case AGPIOC_INFO:
- if (!sc->sc_chipc)
- return (ENXIO);
- case AGPIOC_ACQUIRE:
- case AGPIOC_RELEASE:
- case AGPIOC_SETUP:
- case AGPIOC_ALLOCATE:
- case AGPIOC_DEALLOCATE:
- case AGPIOC_BIND:
- case AGPIOC_UNBIND:
- if (cmd != AGPIOC_INFO && !(flag & FWRITE))
- return (EPERM);
- break;
- }
switch(cmd) {
case AGPIOC_INFO:
- info = (agp_info *)addr;
- bzero(info, sizeof *info);
- info->bridge_id = sc->sc_id;
- if (sc->sc_capoff != 0)
- info->agp_mode = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
- AGP_STATUS + sc->sc_capoff);
- else
- info->agp_mode = 0; /* i810 doesn't have real AGP */
- info->aper_base = sc->sc_apaddr;
- info->aper_size = AGP_GET_APERTURE(sc) >> 20;
- info->pg_total =
- info->pg_system = sc->sc_maxmem >> AGP_PAGE_SHIFT;
- info->pg_used = sc->sc_allocated >> AGP_PAGE_SHIFT;
- break;
+ return (agp_info_user(sc, (agp_info *)addr));
case AGPIOC_ACQUIRE:
- if (sc->sc_state != AGP_ACQUIRE_FREE)
- error = EBUSY;
- else
- sc->sc_state = AGP_ACQUIRE_USER;
- break;
+ return (agp_acquire_helper(sc, AGP_ACQUIRE_USER));
case AGPIOC_RELEASE:
- if (sc->sc_state == AGP_ACQUIRE_FREE)
- break;
-
- if (sc->sc_state != AGP_ACQUIRE_USER) {
- error = EBUSY;
- break;
- }
-
- /*
- * Clear out the aperture and free any
- * outstanding memory blocks.
- */
- TAILQ_FOREACH(mem, &sc->sc_memory, am_link) {
- if (mem->am_is_bound) {
- printf("agp_release_helper: mem %d is bound\n",
- mem->am_id);
- AGP_UNBIND_MEMORY(sc, mem);
- }
- }
- sc->sc_state = AGP_ACQUIRE_FREE;
- break;
+ return (agp_release_helper(sc, AGP_ACQUIRE_USER));
case AGPIOC_SETUP:
- setup = (agp_setup *)addr;
- error = AGP_ENABLE(sc, setup->agp_mode);
- break;
+ return (agp_setup_user(sc, (agp_setup *)addr));
case AGPIOC_ALLOCATE:
- alloc = (agp_allocate *)addr;
- size = alloc->pg_count << AGP_PAGE_SHIFT;
- if (sc->sc_allocated + size > sc->sc_maxmem)
- error = EINVAL;
- else {
- mem = AGP_ALLOC_MEMORY(sc, alloc->type, size);
- if (mem) {
- alloc->key = mem->am_id;
- alloc->physical = mem->am_physical;
- } else
- error = ENOMEM;
- }
- break;
+ return (agp_allocate_user(sc, (agp_allocate *)addr));
case AGPIOC_DEALLOCATE:
- mem = agp_find_memory(sc, *(int *)addr);
- if (mem)
- AGP_FREE_MEMORY(sc, mem);
- else
- error = ENOENT;
- break;
+ return (agp_deallocate_user(sc, *(int *)addr));
case AGPIOC_BIND:
- bind = (agp_bind *)addr;
- mem = agp_find_memory(sc, bind->key);
- if (!mem)
- error = ENOENT;
- else
- error = AGP_BIND_MEMORY(sc, mem,
- bind->pg_start << AGP_PAGE_SHIFT);
- break;
+ return (agp_bind_user(sc, (agp_bind *)addr));
case AGPIOC_UNBIND:
- unbind = (agp_unbind *)addr;
- mem = agp_find_memory(sc, unbind->key);
- if (!mem)
- error = ENOENT;
- else
- error = AGP_UNBIND_MEMORY(sc, mem);
- break;
+ return (agp_unbind_user(sc, (agp_unbind *)addr));
+
default:
- error = ENOTTY;
+ return (ENOTTY);
}
- return (error);
}
-#ifdef notyet
-void
-agp_close(void *v)
+int
+agpclose(dev_t dev, int flags, int devtype, struct proc *p)
{
- struct vga_config *vc = v;
- struct vga_pci_softc *sc = (struct vga_pci_softc *)vc->vc_softc;
+ struct agp_softc *sc =
+ (struct agp_softc *)device_lookup(&agp_cd, AGPUNIT(dev));
struct agp_memory *mem;
/*
- * Clear out the aperture and free any
- * outstanding memory blocks.
- */
- TAILQ_FOREACH(mem, &sc->sc_memory, am_link) {
- if (mem->am_is_bound) {
- AGP_UNBIND_MEMORY(sc, mem);
+ * Clear the GATT and force release on last close
+ */
+ if (sc->sc_state == AGP_ACQUIRE_USER) {
+ while ((mem = TAILQ_FIRST(&sc->sc_memory)) != 0) {
+ if (mem->am_is_bound)
+ AGP_UNBIND_MEMORY(sc, mem);
+ AGP_FREE_MEMORY(sc, mem);
}
+ agp_release_helper(sc, AGP_ACQUIRE_USER);
}
+ sc->sc_opened = 0;
- while (!TAILQ_EMPTY(&sc->sc_memory)) {
- mem = TAILQ_FIRST(&sc->sc_memory);
- AGP_FREE_MEMORY(sc, mem);
- }
-
- sc->sc_state = AGP_ACQUIRE_FREE;
+ return (0);
}
-#endif
struct agp_memory *
-agp_find_memory(struct vga_pci_softc *sc, int id)
+agp_find_memory(struct agp_softc *sc, int id)
{
struct agp_memory *mem;
@@ -302,7 +314,7 @@ agp_find_memory(struct vga_pci_softc *sc, int id)
if (mem->am_id == id)
return (mem);
}
- return 0;
+ return (0);
}
const struct agp_product *
@@ -310,10 +322,6 @@ agp_lookup(struct pci_attach_args *pa)
{
const struct agp_product *ap;
- if (!agp_pchb_pa_set)
- return (NULL);
- agp_pchb_pa_set = 0;
-
/* First find the vendor. */
for (ap = agp_products; ap->ap_attach != NULL; ap++)
if (ap->ap_vendor == PCI_VENDOR(pa->pa_id))
@@ -340,39 +348,30 @@ agp_lookup(struct pci_attach_args *pa)
return (ap);
}
-void
-pciagp_set_pchb(struct pci_attach_args *pa)
-{
- if (!agp_pchb_pa_set) {
- memcpy(&agp_pchb_pa, pa, sizeof *pa);
- agp_pchb_pa_set++;
- }
-}
-
int
-agp_map_aperture(struct vga_pci_softc *sc, u_int32_t bar, u_int32_t memtype)
+agp_map_aperture(struct pci_attach_args *pa, struct agp_softc *sc, u_int32_t bar, u_int32_t memtype)
{
/*
* Find and the aperture. Don't map it (yet), this would
* eat KVA.
*/
- if (pci_mapreg_info(sc->sc_pc, sc->sc_pcitag, bar,
+ if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, bar,
memtype, &sc->sc_apaddr, &sc->sc_apsize,
&sc->sc_apflags) != 0)
- return ENXIO;
+ return (ENXIO);
- return 0;
+ return (0);
}
struct agp_gatt *
-agp_alloc_gatt(struct vga_pci_softc *sc)
+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 nseg;
- gatt = malloc(sizeof(*gatt), M_DEVBUF, M_NOWAIT | M_ZERO);
+ gatt = malloc(sizeof(*gatt), M_AGP, M_NOWAIT | M_ZERO);
if (!gatt)
return (NULL);
gatt->ag_entries = entries;
@@ -380,33 +379,33 @@ agp_alloc_gatt(struct vga_pci_softc *sc)
if (agp_alloc_dmamem(sc->sc_dmat, entries * sizeof(u_int32_t),
0, &gatt->ag_dmamap, (caddr_t *)&gatt->ag_virtual,
&gatt->ag_physical, &gatt->ag_dmaseg, 1, &nseg) != 0)
- return NULL;
+ return (NULL);
gatt->ag_size = entries * sizeof(u_int32_t);
memset(gatt->ag_virtual, 0, gatt->ag_size);
agp_flush_cache();
- return gatt;
+ return (gatt);
}
void
-agp_free_gatt(struct vga_pci_softc *sc, struct agp_gatt *gatt)
+agp_free_gatt(struct agp_softc *sc, struct agp_gatt *gatt)
{
agp_free_dmamem(sc->sc_dmat, gatt->ag_size, gatt->ag_dmamap,
(caddr_t)gatt->ag_virtual, &gatt->ag_dmaseg, 1);
- free(gatt, M_DEVBUF);
+ free(gatt, M_AGP);
}
int
-agp_generic_detach(struct vga_pci_softc *sc)
+agp_generic_detach(struct agp_softc *sc)
{
lockmgr(&sc->sc_lock, LK_DRAIN, NULL);
agp_flush_cache();
- return 0;
+ return (0);
}
int
-agp_generic_enable(struct vga_pci_softc *sc, u_int32_t mode)
+agp_generic_enable(struct agp_softc *sc, u_int32_t mode)
{
pcireg_t tstatus, mstatus;
pcireg_t command;
@@ -415,7 +414,7 @@ agp_generic_enable(struct vga_pci_softc *sc, u_int32_t mode)
if (pci_get_capability(sc->sc_pc, sc->sc_pcitag, PCI_CAP_AGP,
&capoff, NULL) == 0) {
printf("agp_generic_enable: not an AGP capable device\n");
- return -1;
+ return (-1);
}
tstatus = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
@@ -460,27 +459,27 @@ agp_generic_enable(struct vga_pci_softc *sc, u_int32_t mode)
pci_conf_write(sc->sc_pc, sc->sc_pcitag,
sc->sc_capoff + AGP_COMMAND, command);
pci_conf_write(sc->sc_pc, sc->sc_pcitag, capoff + AGP_COMMAND, command);
- return 0;
+ return (0);
}
struct agp_memory *
-agp_generic_alloc_memory(struct vga_pci_softc *sc, int type, vsize_t size)
+agp_generic_alloc_memory(struct agp_softc *sc, int type, vsize_t size)
{
struct agp_memory *mem;
if (type != 0) {
printf("agp_generic_alloc_memory: unsupported type %d\n", type);
- return 0;
+ return (0);
}
- mem = malloc(sizeof *mem, M_DEVBUF, M_WAITOK | M_ZERO);
+ mem = malloc(sizeof *mem, M_AGP, M_WAITOK | M_ZERO);
if (mem == NULL)
- return NULL;
+ return (NULL);
if (bus_dmamap_create(sc->sc_dmat, size, size / PAGE_SIZE + 1,
size, 0, BUS_DMA_NOWAIT, &mem->am_dmamap) != 0) {
- free(mem, M_DEVBUF);
- return NULL;
+ free(mem, M_AGP);
+ return (NULL);
}
mem->am_id = sc->sc_nextid++;
@@ -488,24 +487,24 @@ agp_generic_alloc_memory(struct vga_pci_softc *sc, int type, vsize_t size)
TAILQ_INSERT_TAIL(&sc->sc_memory, mem, am_link);
sc->sc_allocated += size;
- return mem;
+ return (mem);
}
int
-agp_generic_free_memory(struct vga_pci_softc *sc, struct agp_memory *mem)
+agp_generic_free_memory(struct agp_softc *sc, struct agp_memory *mem)
{
if (mem->am_is_bound)
- return EBUSY;
+ return (EBUSY);
sc->sc_allocated -= mem->am_size;
TAILQ_REMOVE(&sc->sc_memory, mem, am_link);
bus_dmamap_destroy(sc->sc_dmat, mem->am_dmamap);
- free(mem, M_DEVBUF);
- return 0;
+ free(mem, M_AGP);
+ return (0);
}
int
-agp_generic_bind_memory(struct vga_pci_softc *sc, struct agp_memory *mem,
+agp_generic_bind_memory(struct agp_softc *sc, struct agp_memory *mem,
off_t offset)
{
bus_dma_segment_t *segs, *seg;
@@ -519,7 +518,7 @@ agp_generic_bind_memory(struct vga_pci_softc *sc, struct agp_memory *mem,
if (mem->am_is_bound) {
printf("AGP: memory already bound\n");
lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
- return EINVAL;
+ return (EINVAL);
}
if (offset < 0
@@ -528,7 +527,7 @@ agp_generic_bind_memory(struct vga_pci_softc *sc, struct agp_memory *mem,
printf("AGP: binding memory at bad offset %#lx\n",
(unsigned long) offset);
lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
- return EINVAL;
+ return (EINVAL);
}
/*
@@ -539,27 +538,27 @@ agp_generic_bind_memory(struct vga_pci_softc *sc, struct agp_memory *mem,
*/
nseg = (mem->am_size + PAGE_SIZE - 1) / PAGE_SIZE;
- segs = malloc(nseg * sizeof *segs, M_DEVBUF, M_WAITOK);
+ segs = malloc(nseg * sizeof *segs, M_AGP, M_WAITOK);
if (segs == NULL) {
lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
AGP_DPF("malloc segs (%u) failed\n",
nseg * sizeof *segs);
- return ENOMEM;
+ return (ENOMEM);
}
if ((error = bus_dmamem_alloc(sc->sc_dmat, mem->am_size, PAGE_SIZE, 0,
segs, nseg, &mem->am_nseg, BUS_DMA_WAITOK)) != 0) {
- free(segs, M_DEVBUF);
+ free(segs, M_AGP);
lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
AGP_DPF("bus_dmamem_alloc failed %d\n", error);
- return error;
+ return (error);
}
if ((error = bus_dmamem_map(sc->sc_dmat, segs, mem->am_nseg,
mem->am_size, &mem->am_virtual, BUS_DMA_WAITOK)) != 0) {
bus_dmamem_free(sc->sc_dmat, segs, mem->am_nseg);
- free(segs, M_DEVBUF);
+ free(segs, M_AGP);
lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
AGP_DPF("bus_dmamem_map failed %d\n", error);
- return error;
+ return (error);
}
if ((error = bus_dmamap_load(sc->sc_dmat, mem->am_dmamap,
mem->am_virtual, mem->am_size, NULL,
@@ -567,10 +566,10 @@ agp_generic_bind_memory(struct vga_pci_softc *sc, struct agp_memory *mem,
bus_dmamem_unmap(sc->sc_dmat, mem->am_virtual,
mem->am_size);
bus_dmamem_free(sc->sc_dmat, segs, mem->am_nseg);
- free(segs, M_DEVBUF);
+ free(segs, M_AGP);
lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
AGP_DPF("bus_dmamap_load failed %d\n", error);
- return error;
+ return (error);
}
mem->am_dmaseg = segs;
@@ -607,10 +606,10 @@ agp_generic_bind_memory(struct vga_pci_softc *sc, struct agp_memory *mem,
mem->am_size);
bus_dmamem_free(sc->sc_dmat, mem->am_dmaseg,
mem->am_nseg);
- free(mem->am_dmaseg, M_DEVBUF);
+ free(mem->am_dmaseg, M_AGP);
lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
AGP_DPF("AGP_BIND_PAGE failed %d\n", error);
- return error;
+ return (error);
}
}
done += seg->ds_len;
@@ -632,11 +631,11 @@ agp_generic_bind_memory(struct vga_pci_softc *sc, struct agp_memory *mem,
lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
- return 0;
+ return (0);
}
int
-agp_generic_unbind_memory(struct vga_pci_softc *sc, struct agp_memory *mem)
+agp_generic_unbind_memory(struct agp_softc *sc, struct agp_memory *mem)
{
int i;
@@ -645,7 +644,7 @@ agp_generic_unbind_memory(struct vga_pci_softc *sc, struct agp_memory *mem)
if (!mem->am_is_bound) {
printf("AGP: memory is not bound\n");
lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
- return EINVAL;
+ return (EINVAL);
}
@@ -663,14 +662,14 @@ agp_generic_unbind_memory(struct vga_pci_softc *sc, struct agp_memory *mem)
bus_dmamem_unmap(sc->sc_dmat, mem->am_virtual, mem->am_size);
bus_dmamem_free(sc->sc_dmat, mem->am_dmaseg, mem->am_nseg);
- free(mem->am_dmaseg, M_DEVBUF);
+ free(mem->am_dmaseg, M_AGP);
mem->am_offset = 0;
mem->am_is_bound = 0;
lockmgr(&sc->sc_lock, LK_RELEASE, NULL);
- return 0;
+ return (0);
}
int
@@ -702,7 +701,7 @@ agp_alloc_dmamem(bus_dma_tag_t tag, size_t size, int flags,
*baddr = (*mapp)->dm_segs[0].ds_addr;
- return 0;
+ return (0);
out:
switch (level) {
case 3:
@@ -718,7 +717,7 @@ out:
break;
}
- return error;
+ return (error);
}
void
@@ -731,3 +730,220 @@ agp_free_dmamem(bus_dma_tag_t tag, size_t size, bus_dmamap_t map,
bus_dmamem_unmap(tag, vaddr, size);
bus_dmamem_free(tag, seg, nseg);
}
+
+/* Helper functions used in both user and kernel APIs */
+
+static int
+agp_acquire_helper(void *dev, enum agp_acquire_state state)
+{
+ struct agp_softc *sc = (struct agp_softc *)dev;
+
+ if (sc->sc_state != AGP_ACQUIRE_FREE)
+ return (EBUSY);
+ sc->sc_state = state;
+
+ return (0);
+}
+
+static int
+agp_release_helper(void *dev, enum agp_acquire_state state)
+{
+ struct agp_softc *sc = (struct agp_softc *)dev;
+ struct agp_memory* mem;
+
+ if (sc->sc_state == AGP_ACQUIRE_FREE)
+ return (0);
+
+ if (sc->sc_state != state)
+ return (EBUSY);
+
+ /*
+ * Clear out the aperture and free any
+ * outstanding memory blocks.
+ */
+ TAILQ_FOREACH(mem, &sc->sc_memory, am_link) {
+ if (mem->am_is_bound) {
+ printf("agp_release_helper: mem %d is bound\n",
+ mem->am_id);
+ AGP_UNBIND_MEMORY(sc, mem);
+ }
+ }
+ sc->sc_state = AGP_ACQUIRE_FREE;
+ return (0);
+}
+
+/* Implementation of the userland ioctl API */
+
+static int
+agp_info_user(void *dev, agp_info *info)
+{
+ struct agp_softc *sc = (struct agp_softc *) dev;
+
+ if (!sc->sc_chipc)
+ return (ENXIO);
+
+ bzero(info, sizeof *info);
+ info->bridge_id = sc->sc_id;
+ if (sc->sc_capoff != 0)
+ info->agp_mode = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
+ AGP_STATUS + sc->sc_capoff);
+ else
+ info->agp_mode = 0; /* i810 doesn't have real AGP */
+ info->aper_base = sc->sc_apaddr;
+ info->aper_size = AGP_GET_APERTURE(sc) >> 20;
+ info->pg_total =
+ info->pg_system = sc->sc_maxmem >> AGP_PAGE_SHIFT;
+ info->pg_used = sc->sc_allocated >> AGP_PAGE_SHIFT;
+
+ return (0);
+}
+
+static int
+agp_setup_user(void *dev, agp_setup *setup)
+{
+ struct agp_softc *sc = (struct agp_softc *) dev;
+ return (AGP_ENABLE(sc, setup->agp_mode));
+}
+
+static int
+agp_allocate_user(void *dev, agp_allocate *alloc)
+{
+ struct agp_softc *sc = (struct agp_softc *) dev;
+ struct agp_memory* mem;
+ size_t size = alloc->pg_count << AGP_PAGE_SHIFT;
+
+ if (sc->sc_allocated + size > sc->sc_maxmem)
+ return (EINVAL);
+
+ mem = AGP_ALLOC_MEMORY(sc, alloc->type, size);
+ if (mem) {
+ alloc->key = mem->am_id;
+ alloc->physical = mem->am_physical;
+ return (0);
+ } else
+ return (ENOMEM);
+}
+
+static int
+agp_deallocate_user(void *dev, int id)
+{
+ struct agp_softc *sc = (struct agp_softc *) dev;
+ struct agp_memory *mem = agp_find_memory(sc, id);
+ if (mem) {
+ AGP_FREE_MEMORY(sc, mem);
+ return (0);
+ } else
+ return (ENOENT);
+}
+
+static int
+agp_bind_user(void *dev, agp_bind *bind)
+{
+ struct agp_softc *sc = (struct agp_softc *) dev;
+ struct agp_memory *mem = agp_find_memory(sc, bind->key);
+
+ if (!mem)
+ return (ENOENT);
+
+ return (AGP_BIND_MEMORY(sc, mem, bind->pg_start << AGP_PAGE_SHIFT));
+}
+
+
+static int
+agp_unbind_user(void *dev, agp_unbind *unbind)
+{
+ struct agp_softc *sc = (struct agp_softc *) dev;
+ struct agp_memory *mem = agp_find_memory(sc, unbind->key);
+
+ if (!mem)
+ return (ENOENT);
+
+ return (AGP_UNBIND_MEMORY(sc, mem));
+}
+
+/* Implementation of the kernel api */
+
+void *
+agp_find_device(int unit)
+{
+ return (device_lookup(&agp_cd, unit));
+}
+
+enum agp_acquire_state
+agp_state(void *dev)
+{
+ struct agp_softc *sc = (struct agp_softc *) dev;
+ return (sc->sc_state);
+}
+
+void
+agp_get_info(void *dev, struct agp_info *info)
+{
+ struct agp_softc *sc = (struct agp_softc *)dev;
+
+ info->ai_mode = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
+ sc->sc_capoff + AGP_STATUS);
+ info->ai_aperture_base = sc->sc_apaddr;
+ info->ai_aperture_size = sc->sc_apsize;
+ info->ai_memory_allowed = sc->sc_maxmem;
+ info->ai_memory_used = sc->sc_allocated;
+}
+
+int
+agp_acquire(void *dev)
+{
+ struct agp_softc *sc = (struct agp_softc *)dev;
+ return (agp_acquire_helper(sc, AGP_ACQUIRE_KERNEL));
+}
+
+int
+agp_release(void *dev)
+{
+ struct agp_softc *sc = (struct agp_softc *)dev;
+ return (agp_release_helper(sc, AGP_ACQUIRE_KERNEL));
+}
+
+int
+agp_enable(void *dev, u_int32_t mode)
+{
+ struct agp_softc *sc = (struct agp_softc *) dev;
+ return (AGP_ENABLE(sc, mode));
+}
+
+void *agp_alloc_memory(void *dev, int type, vsize_t bytes)
+{
+ struct agp_softc *sc = (struct agp_softc *)dev;
+ return ((void *) AGP_ALLOC_MEMORY(sc, type, bytes));
+}
+
+void agp_free_memory(void *dev, void *handle)
+{
+ struct agp_softc *sc = (struct agp_softc *) dev;
+ struct agp_memory *mem = (struct agp_memory *) handle;
+ AGP_FREE_MEMORY(sc, mem);
+}
+
+int agp_bind_memory(void *dev, void *handle, off_t offset)
+{
+ struct agp_softc *sc = (struct agp_softc *) dev;
+ struct agp_memory *mem = (struct agp_memory *) handle;
+ return (AGP_BIND_MEMORY(sc, mem, offset));
+}
+
+int agp_unbind_memory(void *dev, void *handle)
+{
+ struct agp_softc *sc = (struct agp_softc *) dev;
+ struct agp_memory *mem = (struct agp_memory *) handle;
+ return (AGP_UNBIND_MEMORY(sc, mem));
+}
+
+void agp_memory_info(void *dev, void *handle, struct
+ agp_memory_info *mi)
+{
+ struct agp_memory *mem = (struct agp_memory *) handle;
+
+ mi->ami_size = mem->am_size;
+ mi->ami_physical = mem->am_physical;
+ mi->ami_offset = mem->am_offset;
+ mi->ami_is_bound = mem->am_is_bound;
+}
diff --git a/sys/dev/pci/agp_ali.c b/sys/dev/pci/agp_ali.c
index aa256b6ba84..21380406163 100644
--- a/sys/dev/pci/agp_ali.c
+++ b/sys/dev/pci/agp_ali.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: agp_ali.c,v 1.3 2007/08/04 19:40:25 reyk Exp $ */
+/* $OpenBSD: agp_ali.c,v 1.4 2007/11/25 17:11:12 oga Exp $ */
/* $NetBSD: agp_ali.c,v 1.2 2001/09/15 00:25:00 thorpej Exp $ */
@@ -55,11 +55,11 @@ struct agp_ali_softc {
struct agp_gatt *gatt;
};
-u_int32_t agp_ali_get_aperture(struct vga_pci_softc *);
-int agp_ali_set_aperture(struct vga_pci_softc *sc, u_int32_t);
-int agp_ali_bind_page(struct vga_pci_softc *, off_t, bus_addr_t);
-int agp_ali_unbind_page(struct vga_pci_softc *, off_t);
-void agp_ali_flush_tlb(struct vga_pci_softc *);
+u_int32_t agp_ali_get_aperture(struct agp_softc *);
+int agp_ali_set_aperture(struct agp_softc *sc, u_int32_t);
+int agp_ali_bind_page(struct agp_softc *, off_t, bus_addr_t);
+int agp_ali_unbind_page(struct agp_softc *, off_t);
+void agp_ali_flush_tlb(struct agp_softc *);
struct agp_methods agp_ali_methods = {
agp_ali_get_aperture,
@@ -75,14 +75,13 @@ struct agp_methods agp_ali_methods = {
};
int
-agp_ali_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
- struct pci_attach_args *pchb_pa)
+agp_ali_attach(struct agp_softc *sc, struct pci_attach_args *pa)
{
struct agp_ali_softc *asc;
struct agp_gatt *gatt;
pcireg_t reg;
- asc = malloc(sizeof *asc, M_DEVBUF, M_NOWAIT);
+ asc = malloc(sizeof *asc, M_AGP, M_NOWAIT);
if (asc == NULL) {
printf(": failed to allocate softc\n");
return (ENOMEM);
@@ -90,9 +89,9 @@ agp_ali_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
sc->sc_chipc = asc;
sc->sc_methods = &agp_ali_methods;
- if (agp_map_aperture(sc, AGP_APBASE, PCI_MAPREG_TYPE_MEM) != 0) {
+ if (agp_map_aperture(pa, sc, AGP_APBASE, PCI_MAPREG_TYPE_MEM) != 0) {
printf(": failed to map aperture\n");
- free(asc, M_DEVBUF);
+ free(asc, M_AGP);
return (ENXIO);
}
@@ -130,7 +129,7 @@ agp_ali_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
#if 0
int
-agp_ali_detach(struct vga_pci_softc *sc)
+agp_ali_detach(struct agp_softc *sc)
{
int error;
pcireg_t reg;
@@ -175,7 +174,7 @@ static const u_int32_t agp_ali_table[] = {
#define agp_ali_table_size (sizeof(agp_ali_table) / sizeof(agp_ali_table[0]))
u_int32_t
-agp_ali_get_aperture(struct vga_pci_softc *sc)
+agp_ali_get_aperture(struct agp_softc *sc)
{
int i;
@@ -191,7 +190,7 @@ agp_ali_get_aperture(struct vga_pci_softc *sc)
}
int
-agp_ali_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
+agp_ali_set_aperture(struct agp_softc *sc, u_int32_t aperture)
{
int i;
pcireg_t reg;
@@ -200,7 +199,7 @@ agp_ali_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
if (agp_ali_table[i] == aperture)
break;
if (i == agp_ali_table_size)
- return EINVAL;
+ return (EINVAL);
reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_ALI_ATTBASE);
reg &= ~0xff;
@@ -210,7 +209,7 @@ agp_ali_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
}
int
-agp_ali_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
+agp_ali_bind_page(struct agp_softc *sc, off_t offset, bus_addr_t physical)
{
struct agp_ali_softc *asc = sc->sc_chipc;
@@ -222,7 +221,7 @@ agp_ali_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
}
int
-agp_ali_unbind_page(struct vga_pci_softc *sc, off_t offset)
+agp_ali_unbind_page(struct agp_softc *sc, off_t offset)
{
struct agp_ali_softc *asc = sc->sc_chipc;
@@ -234,7 +233,7 @@ agp_ali_unbind_page(struct vga_pci_softc *sc, off_t offset)
}
void
-agp_ali_flush_tlb(struct vga_pci_softc *sc)
+agp_ali_flush_tlb(struct agp_softc *sc)
{
pcireg_t reg;
diff --git a/sys/dev/pci/agp_amd.c b/sys/dev/pci/agp_amd.c
index d09027a3183..ce9c3b2f850 100644
--- a/sys/dev/pci/agp_amd.c
+++ b/sys/dev/pci/agp_amd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: agp_amd.c,v 1.4 2007/10/06 23:50:54 krw Exp $ */
+/* $OpenBSD: agp_amd.c,v 1.5 2007/11/25 17:11:12 oga Exp $ */
/* $NetBSD: agp_amd.c,v 1.6 2001/10/06 02:48:50 thorpej Exp $ */
@@ -74,11 +74,11 @@ struct agp_amd_softc {
bus_space_tag_t iot;
};
-static u_int32_t agp_amd_get_aperture(struct vga_pci_softc *);
-static int agp_amd_set_aperture(struct vga_pci_softc *, u_int32_t);
-static int agp_amd_bind_page(struct vga_pci_softc *, off_t, bus_addr_t);
-static int agp_amd_unbind_page(struct vga_pci_softc *, off_t);
-static void agp_amd_flush_tlb(struct vga_pci_softc *);
+static u_int32_t agp_amd_get_aperture(struct agp_softc *);
+static int agp_amd_set_aperture(struct agp_softc *, u_int32_t);
+static int agp_amd_bind_page(struct agp_softc *, off_t, bus_addr_t);
+static int agp_amd_unbind_page(struct agp_softc *, off_t);
+static void agp_amd_flush_tlb(struct agp_softc *);
struct agp_methods agp_amd_methods = {
@@ -96,7 +96,7 @@ struct agp_methods agp_amd_methods = {
static struct agp_amd_gatt *
-agp_amd_alloc_gatt(struct vga_pci_softc *sc)
+agp_amd_alloc_gatt(struct agp_softc *sc)
{
u_int32_t apsize = AGP_GET_APERTURE(sc);
u_int32_t entries = apsize >> AGP_PAGE_SHIFT;
@@ -104,7 +104,7 @@ agp_amd_alloc_gatt(struct vga_pci_softc *sc)
int i, npages;
caddr_t vdir;
- gatt = malloc(sizeof(struct agp_amd_gatt), M_DEVBUF, M_NOWAIT);
+ gatt = malloc(sizeof(struct agp_amd_gatt), M_AGP, M_NOWAIT);
if (!gatt)
return (0);
@@ -113,7 +113,7 @@ agp_amd_alloc_gatt(struct vga_pci_softc *sc)
&gatt->ag_dmamap, &vdir, &gatt->ag_pdir,
&gatt->ag_dmaseg, 1, &gatt->ag_nseg) != 0) {
printf("failed to allocate GATT\n");
- free(gatt, M_DEVBUF);
+ free(gatt, M_AGP);
return (NULL);
}
@@ -145,42 +145,42 @@ agp_amd_alloc_gatt(struct vga_pci_softc *sc)
#if 0
static void
-agp_amd_free_gatt(struct vga_pci_softc *sc, struct agp_amd_gatt *gatt)
+agp_amd_free_gatt(struct agp_softc *sc, struct agp_amd_gatt *gatt)
{
agp_free_dmamem(sc->sc_dmat, gatt->ag_size,
gatt->ag_dmamap, (caddr_t)gatt->ag_virtual, &gatt->ag_dmaseg,
gatt->ag_nseg);
- free(gatt, M_DEVBUF);
+ free(gatt, M_AGP);
}
#endif
int
-agp_amd_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa, struct pci_attach_args *pchb_pa)
+agp_amd_attach(struct agp_softc *sc, struct pci_attach_args *pa)
{
struct agp_amd_softc *asc;
struct agp_amd_gatt *gatt;
pcireg_t reg;
int error;
- asc = malloc(sizeof *asc, M_DEVBUF, M_NOWAIT | M_ZERO);
+ asc = malloc(sizeof *asc, M_AGP, M_NOWAIT | M_ZERO);
if (asc == NULL) {
printf(": can't allocate softc\n");
/* agp_generic_detach(sc) */
return (ENOMEM);
}
- error = pci_mapreg_map(pchb_pa, AGP_AMD751_REGISTERS,
- PCI_MAPREG_TYPE_MEM,0, &asc->iot, &asc->ioh, NULL, NULL, 0);
+ error = pci_mapreg_map(pa, AGP_AMD751_REGISTERS,
+ PCI_MAPREG_TYPE_MEM, 0, &asc->iot, &asc->ioh, NULL, NULL, 0);
if (error != 0) {
printf(": can't map AGP registers\n");
agp_generic_detach(sc);
return (error);
}
- if (agp_map_aperture(sc, AGP_APBASE, PCI_MAPREG_TYPE_MEM) != 0) {
+ if (agp_map_aperture(pa, sc, AGP_APBASE, PCI_MAPREG_TYPE_MEM) != 0) {
printf(": can't map aperture\n");
agp_generic_detach(sc);
- free(asc, M_DEVBUF);
+ free(asc, M_AGP);
return (ENXIO);
}
sc->sc_methods = &agp_amd_methods;
@@ -221,7 +221,7 @@ agp_amd_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa, struct pci_
#if 0
static int
-agp_amd_detach(struct vga_pci_softc *sc)
+agp_amd_detach(struct agp_softc *sc)
{
pcireg_t reg;
struct agp_amd_softc *asc = sc->sc_chipc;
@@ -250,7 +250,7 @@ agp_amd_detach(struct vga_pci_softc *sc)
#endif
static u_int32_t
-agp_amd_get_aperture(struct vga_pci_softc *sc)
+agp_amd_get_aperture(struct agp_softc *sc)
{
int vas;
@@ -264,7 +264,7 @@ agp_amd_get_aperture(struct vga_pci_softc *sc)
}
static int
-agp_amd_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
+agp_amd_set_aperture(struct agp_softc *sc, u_int32_t aperture)
{
int vas;
pcireg_t reg;
@@ -288,7 +288,7 @@ agp_amd_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
}
static int
-agp_amd_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
+agp_amd_bind_page(struct agp_softc *sc, off_t offset, bus_addr_t physical)
{
struct agp_amd_softc *asc = sc->sc_chipc;
@@ -300,7 +300,7 @@ agp_amd_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
}
static int
-agp_amd_unbind_page(struct vga_pci_softc *sc, off_t offset)
+agp_amd_unbind_page(struct agp_softc *sc, off_t offset)
{
struct agp_amd_softc *asc = sc->sc_chipc;
@@ -312,7 +312,7 @@ agp_amd_unbind_page(struct vga_pci_softc *sc, off_t offset)
}
static void
-agp_amd_flush_tlb(struct vga_pci_softc *sc)
+agp_amd_flush_tlb(struct agp_softc *sc)
{
struct agp_amd_softc *asc = sc->sc_chipc;
diff --git a/sys/dev/pci/agp_i810.c b/sys/dev/pci/agp_i810.c
index 4af86c1db1d..f0414dd925f 100644
--- a/sys/dev/pci/agp_i810.c
+++ b/sys/dev/pci/agp_i810.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: agp_i810.c,v 1.17 2007/10/06 23:50:54 krw Exp $ */
+/* $OpenBSD: agp_i810.c,v 1.18 2007/11/25 17:11:12 oga Exp $ */
/* $NetBSD: agp_i810.c,v 1.15 2003/01/31 00:07:39 thorpej Exp $ */
/*-
@@ -50,12 +50,28 @@
#include <machine/bus.h>
+#include "agp_intel.h"
+
#define READ1(off) bus_space_read_1(isc->bst, isc->bsh, off)
#define READ4(off) bus_space_read_4(isc->bst, isc->bsh, off)
#define WRITE4(off,v) bus_space_write_4(isc->bst, isc->bsh, off, v)
-#define WRITEGTT(off,v) bus_space_write_4(isc->gtt_bst, isc->gtt_bsh, off, v)
+#define WRITEGTT(off,v) \
+ do { \
+ if (isc->chiptype == CHIP_I915) { \
+ bus_space_write_4(isc->gtt_bst, isc->gtt_bsh, \
+ (u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, \
+ (v) ? ((v)|1) : 0); \
+ } else if (isc->chiptype == CHIP_I965) { \
+ WRITE4(AGP_I965_GTT + \
+ (u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, \
+ (v) ? ((v) | 1) : 0); \
+ } else { \
+ WRITE4(AGP_I810_GTT + \
+ (u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, \
+ (v) ? ((v) | 1) : 0); \
+ } \
+ } while (0)
-#define WRITE_GATT(off, v) agp_i810_write_gatt(isc, off, v)
enum {
CHIP_I810 = 0, /* i810/i815 */
@@ -66,6 +82,7 @@ enum {
};
struct agp_i810_softc {
+ u_int32_t initial_aperture; /* aperture size at startup */
struct agp_gatt *gatt;
int chiptype; /* i810-like or i830 */
u_int32_t dcache_size; /* i810 only */
@@ -76,22 +93,22 @@ struct agp_i810_softc {
bus_size_t bsz; /* bus_space size */
bus_space_tag_t gtt_bst; /* GATT bus_space tag */
bus_space_handle_t gtt_bsh; /* GATT bus_space handle */
- struct pci_attach_args bridge_pa;
+ struct pci_attach_args vga_pa;
};
-u_int32_t agp_i810_get_aperture(struct vga_pci_softc *);
-int agp_i810_set_aperture(struct vga_pci_softc *, u_int32_t);
-int agp_i810_bind_page(struct vga_pci_softc *, off_t, bus_addr_t);
-int agp_i810_unbind_page(struct vga_pci_softc *, off_t);
-void agp_i810_flush_tlb(struct vga_pci_softc *);
-int agp_i810_enable(struct vga_pci_softc *, u_int32_t mode);
+int agp_i810_vgamatch(struct pci_attach_args *);
+u_int32_t agp_i810_get_aperture(struct agp_softc *);
+int agp_i810_set_aperture(struct agp_softc *, u_int32_t);
+int agp_i810_bind_page(struct agp_softc *, off_t, bus_addr_t);
+int agp_i810_unbind_page(struct agp_softc *, off_t);
+void agp_i810_flush_tlb(struct agp_softc *);
+int agp_i810_enable(struct agp_softc *, u_int32_t mode);
struct agp_memory *
- agp_i810_alloc_memory(struct vga_pci_softc *, int, vsize_t);
-int agp_i810_free_memory(struct vga_pci_softc *, struct agp_memory *);
-int agp_i810_bind_memory(struct vga_pci_softc *, struct agp_memory *,
+ agp_i810_alloc_memory(struct agp_softc *, int, vsize_t);
+int agp_i810_free_memory(struct agp_softc *, struct agp_memory *);
+int agp_i810_bind_memory(struct agp_softc *, struct agp_memory *,
off_t);
-int agp_i810_unbind_memory(struct vga_pci_softc *, struct agp_memory *);
-void agp_i810_write_gatt(struct agp_i810_softc *, bus_size_t, u_int32_t);
+int agp_i810_unbind_memory(struct agp_softc *, struct agp_memory *);
struct agp_methods agp_i810_methods = {
agp_i810_get_aperture,
@@ -106,9 +123,41 @@ struct agp_methods agp_i810_methods = {
agp_i810_unbind_memory,
};
+/* XXXthorpej -- duplicated code (see arch/i386/pci/pchb.c) */
int
-agp_i810_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
- struct pci_attach_args *pchb_pa)
+agp_i810_vgamatch(struct pci_attach_args *pa)
+{
+
+ if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY ||
+ PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_VGA)
+ return (0);
+
+ switch (PCI_PRODUCT(pa->pa_id)) {
+ case PCI_PRODUCT_INTEL_82810_GC:
+ case PCI_PRODUCT_INTEL_82810_DC100_GC:
+ case PCI_PRODUCT_INTEL_82810E_GC:
+ case PCI_PRODUCT_INTEL_82815_FULL_GRAPH:
+ case PCI_PRODUCT_INTEL_82830MP_IV:
+ case PCI_PRODUCT_INTEL_82845G_IGD:
+ case PCI_PRODUCT_INTEL_82852GM_AGP:
+ case PCI_PRODUCT_INTEL_82865_IGD:
+ case PCI_PRODUCT_INTEL_82915G_IGD:
+ case PCI_PRODUCT_INTEL_82915GM_IGD:
+ case PCI_PRODUCT_INTEL_82945G_IGD_1:
+ case PCI_PRODUCT_INTEL_82945GM_IGD:
+ case PCI_PRODUCT_INTEL_82945GM_IGD_S:
+ case PCI_PRODUCT_INTEL_82Q963_IGD_1:
+ case PCI_PRODUCT_INTEL_82Q963_IGD_2:
+ case PCI_PRODUCT_INTEL_82965_IGD_1:
+ case PCI_PRODUCT_INTEL_82965_IGD_2:
+ return (1);
+ }
+
+ return (0);
+}
+
+int
+agp_i810_attach(struct agp_softc *sc, struct pci_attach_args *pa)
{
struct agp_i810_softc *isc;
struct agp_gatt *gatt;
@@ -116,16 +165,34 @@ agp_i810_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
int error;
u_int memtype = 0;
- isc = malloc(sizeof *isc, M_DEVBUF, M_NOWAIT | M_ZERO);
+ isc = malloc(sizeof *isc, M_AGP, M_NOWAIT | M_ZERO);
if (isc == NULL) {
printf(": can't allocate chipset-specific softc\n");
return (ENOMEM);
}
sc->sc_chipc = isc;
sc->sc_methods = &agp_i810_methods;
- memcpy(&isc->bridge_pa, pchb_pa, sizeof *pchb_pa);
- switch (PCI_PRODUCT(pa->pa_id)) {
+ if (pci_find_device(&isc->vga_pa, agp_i810_vgamatch) == 0) {
+#if NAGP_INTEL > 0
+
+ switch (PCI_PRODUCT(pa->pa_id)) {
+ case PCI_PRODUCT_INTEL_82840_HB:
+ case PCI_PRODUCT_INTEL_82865_IO_1:
+ case PCI_PRODUCT_INTEL_82845G:
+ case PCI_PRODUCT_INTEL_82815_FULL_HUB:
+ return (agp_intel_attach(sc, pa));
+ }
+#endif
+ printf(": can't find internal VGA device config space\n");
+ free(isc, M_AGP);
+ return (ENOENT);
+ }
+
+ /* XXXfvdl */
+ sc->sc_dmat = isc->vga_pa.pa_dmat;
+
+ switch (PCI_PRODUCT(isc->vga_pa.pa_id)) {
case PCI_PRODUCT_INTEL_82810_GC:
case PCI_PRODUCT_INTEL_82810_DC100_GC:
case PCI_PRODUCT_INTEL_82810E_GC:
@@ -144,9 +211,13 @@ agp_i810_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
case PCI_PRODUCT_INTEL_82915GM_IGD:
case PCI_PRODUCT_INTEL_82945G_IGD_1:
case PCI_PRODUCT_INTEL_82945GM_IGD:
+ case PCI_PRODUCT_INTEL_82945GM_IGD_S:
isc->chiptype = CHIP_I915;
break;
case PCI_PRODUCT_INTEL_82965_IGD_1:
+ case PCI_PRODUCT_INTEL_82965_IGD_2:
+ case PCI_PRODUCT_INTEL_82Q963_IGD_1:
+ case PCI_PRODUCT_INTEL_82Q963_IGD_2:
case PCI_PRODUCT_INTEL_82965GM_IGD_1:
isc->chiptype = CHIP_I965;
break;
@@ -156,34 +227,37 @@ agp_i810_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
case CHIP_I915:
gmaddr = AGP_I915_GMADR;
mmaddr = AGP_I915_MMADR;
+ memtype = PCI_MAPREG_TYPE_MEM;
break;
case CHIP_I965:
gmaddr = AGP_I965_GMADR;
mmaddr = AGP_I965_MMADR;
- memtype = PCI_MAPREG_MEM_TYPE_64BIT;
+ memtype = PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT;
break;
default:
gmaddr = AGP_APBASE;
mmaddr = AGP_I810_MMADR;
+ memtype = PCI_MAPREG_TYPE_MEM;
break;
}
- error = agp_map_aperture(sc, gmaddr, memtype);
+ error = agp_map_aperture(&isc->vga_pa, sc, gmaddr, memtype);
if (error != 0) {
printf(": can't map aperture\n");
- free(isc, M_DEVBUF);
+ free(isc, M_AGP);
return (error);
}
- error = pci_mapreg_map(pa, mmaddr, memtype, 0,
+ error = pci_mapreg_map(&isc->vga_pa, mmaddr, memtype, 0,
&isc->bst, &isc->bsh, NULL, &isc->bsz, 0);
if (error != 0) {
printf(": can't map mmadr registers\n");
+ agp_generic_detach(sc);
return (error);
}
if (isc->chiptype == CHIP_I915) {
- error = pci_mapreg_map(pa, AGP_I915_GTTADR, memtype,
+ error = pci_mapreg_map(&isc->vga_pa, AGP_I915_GTTADR, memtype,
0, &isc->gtt_bst, &isc->gtt_bsh, NULL, NULL, 0);
if (error != 0) {
printf(": can't map gatt registers\n");
@@ -192,7 +266,9 @@ agp_i810_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
}
}
- gatt = malloc(sizeof(struct agp_gatt), M_DEVBUF, M_NOWAIT);
+ 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);
@@ -213,7 +289,7 @@ agp_i810_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
if (agp_alloc_dmamem(sc->sc_dmat, 64 * 1024,
0, &gatt->ag_dmamap, (caddr_t *)&gatt->ag_virtual,
&gatt->ag_physical, &gatt->ag_dmaseg, 1, &dummyseg) != 0) {
- free(gatt, M_DEVBUF);
+ free(gatt, M_AGP);
agp_generic_detach(sc);
return (ENOMEM);
}
@@ -230,8 +306,7 @@ agp_i810_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
u_int32_t pgtblctl;
u_int16_t gcc1;
- reg = pci_conf_read(isc->bridge_pa.pa_pc,
- isc->bridge_pa.pa_tag, AGP_I830_GCC1);
+ reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_I830_GCC1);
gcc1 = (u_int16_t)(reg >> 16);
switch (gcc1 & AGP_I830_GCC1_GMS) {
case AGP_I830_GCC1_GMS_STOLEN_512:
@@ -263,152 +338,75 @@ agp_i810_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
WRITE4(AGP_I810_PGTBL_CTL, pgtblctl);
gatt->ag_physical = pgtblctl & ~1;
- } else if (isc->chiptype == CHIP_I915) {
- /* The 915G automatically initializes the 256k gatt on boot. */
+ } else if (isc->chiptype == CHIP_I855 || isc->chiptype == CHIP_I915 ||
+ isc->chiptype == CHIP_I965) {
pcireg_t reg;
- u_int32_t pgtblctl;
+ u_int32_t pgtblctl, stolen;
u_int16_t gcc1;
- reg = pci_conf_read(isc->bridge_pa.pa_pc,
- isc->bridge_pa.pa_tag, AGP_I855_GCC1);
- gcc1 = (u_int16_t)(reg >> 16);
- switch (gcc1 & AGP_I855_GCC1_GMS) {
- case AGP_I855_GCC1_GMS_STOLEN_1M:
- isc->stolen = (1024 - 260) * 1024 / 4096;
- break;
- case AGP_I855_GCC1_GMS_STOLEN_4M:
- isc->stolen = (4096 - 260) * 1024 / 4096;
- break;
- case AGP_I855_GCC1_GMS_STOLEN_8M:
- isc->stolen = (8192 - 260) * 1024 / 4096;
- break;
- case AGP_I855_GCC1_GMS_STOLEN_16M:
- isc->stolen = (16384 - 260) * 1024 / 4096;
- break;
- case AGP_I855_GCC1_GMS_STOLEN_32M:
- isc->stolen = (32768 - 260) * 1024 / 4096;
+ /* Stolen memory is set up at the beginning of the aperture by
+ * the BIOS, consisting of the GATT followed by 4kb for the
+ * BIOS display.
+ */
+ switch (isc->chiptype) {
+ case CHIP_I855:
+ /* The 855GM automatically initializes the 128k gatt on boot. */
+ stolen = 128 + 4;
break;
- case AGP_I915_GCC1_GMS_STOLEN_48M:
- isc->stolen = (49152 - 260) * 1024 / 4096;
+ case CHIP_I915:
+ /* The 915G automatically initializes the 256k gatt on boot. */
+ stolen = 256 + 4;
break;
- case AGP_I915_GCC1_GMS_STOLEN_64M:
- isc->stolen = (65536 - 260) * 1024 / 4096;
+ case CHIP_I965:
+ switch (READ4(AGP_I810_PGTBL_CTL) &
+ AGP_I810_PGTBL_SIZE_MASK) {
+ case AGP_I810_PGTBL_SIZE_512KB:
+ stolen = 512 + 4;
+ break;
+ case AGP_I810_PGTBL_SIZE_256KB:
+ stolen = 256 + 4;
+ break;
+ case AGP_I810_PGTBL_SIZE_128KB:
+ default:
+ stolen = 128 + 4;
+ break;
+ }
break;
default:
- isc->stolen = 0;
- printf(
- ": unknown memory configuration, disabling\n");
+ printf(": bad chiptype\n");
agp_generic_detach(sc);
return (EINVAL);
- }
-#ifdef DEBUG
- if (isc->stolen > 0) {
- printf(": detected %dk stolen memory",
- isc->stolen * 4);
- }
-#endif
-
- /* 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;
- } else if (isc->chiptype == CHIP_I965) {
- pcireg_t reg;
- u_int32_t pgtblctl;
- u_int16_t gcc1;
- u_int32_t gttsize;
-
- switch (READ4(AGP_I810_PGTBL_CTL) &
- AGP_I810_PGTBL_SIZE_MASK) {
- case AGP_I810_PGTBL_SIZE_512KB:
- gttsize = 512 + 4;
- break;
- case AGP_I810_PGTBL_SIZE_256KB:
- gttsize = 256 + 4;
- break;
- case AGP_I810_PGTBL_SIZE_128KB:
- default:
- gttsize = 128 + 4;
- break;
- }
+ }
- reg = pci_conf_read(isc->bridge_pa.pa_pc,
- isc->bridge_pa.pa_tag, AGP_I855_GCC1);
+ reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_I855_GCC1);
gcc1 = (u_int16_t)(reg >> 16);
switch (gcc1 & AGP_I855_GCC1_GMS) {
case AGP_I855_GCC1_GMS_STOLEN_1M:
- isc->stolen = (1024 - gttsize) * 1024 / 4096;
+ isc->stolen = (1024 - stolen) * 1024 / 4096;
break;
case AGP_I855_GCC1_GMS_STOLEN_4M:
- isc->stolen = (4096 - gttsize) * 1024 / 4096;
+ isc->stolen = (4096 - stolen) * 1024 / 4096;
break;
case AGP_I855_GCC1_GMS_STOLEN_8M:
- isc->stolen = (8192 - gttsize) * 1024 / 4096;
+ isc->stolen = (8192 - stolen) * 1024 / 4096;
break;
case AGP_I855_GCC1_GMS_STOLEN_16M:
- isc->stolen = (16384 - gttsize) * 1024 / 4096;
+ isc->stolen = (16384 - stolen) * 1024 / 4096;
break;
case AGP_I855_GCC1_GMS_STOLEN_32M:
- isc->stolen = (32768 - gttsize) * 1024 / 4096;
+ isc->stolen = (32768 - stolen) * 1024 / 4096;
break;
case AGP_I915_GCC1_GMS_STOLEN_48M:
- isc->stolen = (49152 - gttsize) * 1024 / 4096;
+ isc->stolen = (49152 - stolen) * 1024 / 4096;
break;
case AGP_I915_GCC1_GMS_STOLEN_64M:
- isc->stolen = (65536 - gttsize) * 1024 / 4096;
+ isc->stolen = (65536 - stolen) * 1024 / 4096;
break;
case AGP_G33_GCC1_GMS_STOLEN_128M:
- isc->stolen = (131072 - gttsize) * 1024 / 4096;
+ isc->stolen = (131072 - stolen) * 1024 / 4096;
break;
case AGP_G33_GCC1_GMS_STOLEN_256M:
- isc->stolen = (262144 - gttsize) * 1024 / 4096;
- break;
- default:
- isc->stolen = 0;
- printf(": unknown memory configuration 0x%x, "
- "disabling\n", reg);
- agp_generic_detach(sc);
- return (EINVAL);
- }
-#ifdef DEBUG
- if (isc->stolen > 0) {
- printf(": detected %dk stolen memory",
- isc->stolen * 4);
- }
-#endif
-
- /* 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;
- } else { /* CHIP_I855 */
- /* The 855GM automatically initializes the 128k gatt on boot. */
- pcireg_t reg;
- u_int32_t pgtblctl;
- u_int16_t gcc1;
-
- reg = pci_conf_read(isc->bridge_pa.pa_pc,
- isc->bridge_pa.pa_tag, AGP_I855_GCC1);
- gcc1 = (u_int16_t)(reg >> 16);
- switch (gcc1 & AGP_I855_GCC1_GMS) {
- case AGP_I855_GCC1_GMS_STOLEN_1M:
- isc->stolen = (1024 - 132) * 1024 / 4096;
- break;
- case AGP_I855_GCC1_GMS_STOLEN_4M:
- isc->stolen = (4096 - 132) * 1024 / 4096;
- break;
- case AGP_I855_GCC1_GMS_STOLEN_8M:
- isc->stolen = (8192 - 132) * 1024 / 4096;
- break;
- case AGP_I855_GCC1_GMS_STOLEN_16M:
- isc->stolen = (16384 - 132) * 1024 / 4096;
- break;
- case AGP_I855_GCC1_GMS_STOLEN_32M:
- isc->stolen = (32768 - 132) * 1024 / 4096;
+ isc->stolen = (262144 - stolen) * 1024 / 4096;
break;
default:
isc->stolen = 0;
@@ -440,8 +438,42 @@ agp_i810_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
return (0);
}
+#if 0
+static int
+agp_i810_detach(struct agp_softc *sc)
+{
+ int error;
+ struct agp_i810_softc *isc = sc->sc_chipc;
+
+ error = agp_generic_detach(sc);
+ if (error)
+ return (error);
+
+ /* Clear the GATT base. */
+ if (sc->chiptype == CHIP_I810) {
+ WRITE4(AGP_I810_PGTBL_CTL, 0);
+ } else {
+ unsigned int pgtblctl;
+ pgtblctl = READ4(AGP_I810_PGTBL_CTL);
+ pgtblctl &= ~1;
+ WRITE4(AGP_I810_PGTBL_CTL, pgtblctl);
+ }
+
+ /* Put the aperture back the way it started. */
+ AGP_SET_APERTURE(sc, isc->initial_aperture);
+
+ if (sc->chiptype == CHIP_I810) {
+ agp_free_dmamem(sc->sc_dmat, gatt->ag_size, gatt->ag_dmamap,
+ (void *)gatt->ag_virtual, &gatt->ag_dmaseg, 1);
+ }
+ free(sc->gatt, M_AGP);
+
+ return (0);
+}
+#endif
+
u_int32_t
-agp_i810_get_aperture(struct vga_pci_softc *sc)
+agp_i810_get_aperture(struct agp_softc *sc)
{
struct agp_i810_softc *isc = sc->sc_chipc;
pcireg_t reg;
@@ -449,8 +481,7 @@ agp_i810_get_aperture(struct vga_pci_softc *sc)
if (isc->chiptype == CHIP_I810) {
u_int16_t miscc;
- reg = pci_conf_read(isc->bridge_pa.pa_pc,
- isc->bridge_pa.pa_tag, AGP_I810_SMRAM);
+ reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_I810_SMRAM);
miscc = (u_int16_t)(reg >> 16);
if ((miscc & AGP_I810_MISCC_WINSIZE) ==
AGP_I810_MISCC_WINSIZE_32)
@@ -460,24 +491,21 @@ agp_i810_get_aperture(struct vga_pci_softc *sc)
} else if (isc->chiptype == CHIP_I830) {
u_int16_t gcc1;
- reg = pci_conf_read(isc->bridge_pa.pa_pc,
- isc->bridge_pa.pa_tag, AGP_I830_GCC0);
+ reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_I830_GCC0);
gcc1 = (u_int16_t)(reg >> 16);
if ((gcc1 & AGP_I830_GCC1_GMASIZE) == AGP_I830_GCC1_GMASIZE_64)
return (64 * 1024 * 1024);
else
return (128 * 1024 * 1024);
} else if (isc->chiptype == CHIP_I915) {
- reg = pci_conf_read(isc->bridge_pa.pa_pc,
- isc->bridge_pa.pa_tag, AGP_I915_MSAC);
+ reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_I915_MSAC);
if ((reg & AGP_I915_MSAC_GMASIZE) == AGP_I915_MSAC_GMASIZE_128) {
return (128 * 1024 * 1024);
} else {
return (256 * 1024 * 1024);
}
} else if (isc->chiptype == CHIP_I965) {
- reg = pci_conf_read(isc->bridge_pa.pa_pc,
- isc->bridge_pa.pa_tag, AGP_I965_MSAC);
+ reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_I965_MSAC);
switch (reg & AGP_I965_MSAC_GMASIZE) {
case AGP_I965_MSAC_GMASIZE_128:
return (128 * 1024 * 1024);
@@ -493,7 +521,7 @@ agp_i810_get_aperture(struct vga_pci_softc *sc)
}
int
-agp_i810_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
+agp_i810_set_aperture(struct agp_softc *sc, u_int32_t aperture)
{
struct agp_i810_softc *isc = sc->sc_chipc;
pcireg_t reg;
@@ -510,8 +538,7 @@ agp_i810_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
return (EINVAL);
}
- reg = pci_conf_read(isc->bridge_pa.pa_pc,
- isc->bridge_pa.pa_tag, AGP_I810_SMRAM);
+ reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_I810_SMRAM);
miscc = (u_int16_t)(reg >> 16);
miscc &= ~AGP_I810_MISCC_WINSIZE;
if (aperture == 32 * 1024 * 1024)
@@ -521,8 +548,7 @@ agp_i810_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
reg &= 0x0000ffff;
reg |= ((pcireg_t)miscc) << 16;
- pci_conf_write(isc->bridge_pa.pa_pc,
- isc->bridge_pa.pa_tag, AGP_I810_SMRAM, reg);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_I810_SMRAM, reg);
} else if (isc->chiptype == CHIP_I830) {
u_int16_t gcc1;
@@ -531,8 +557,7 @@ agp_i810_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
printf("agp: bad aperture size %d\n", aperture);
return (EINVAL);
}
- reg = pci_conf_read(isc->bridge_pa.pa_pc,
- isc->bridge_pa.pa_tag, AGP_I830_GCC0);
+ reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_I830_GCC0);
gcc1 = (u_int16_t)(reg >> 16);
gcc1 &= ~AGP_I830_GCC1_GMASIZE;
if (aperture == 64 * 1024 * 1024)
@@ -542,26 +567,22 @@ agp_i810_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
reg &= 0x0000ffff;
reg |= ((pcireg_t)gcc1) << 16;
- pci_conf_write(isc->bridge_pa.pa_pc,
- isc->bridge_pa.pa_tag, AGP_I830_GCC0, reg);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_I830_GCC0, reg);
} else if (isc->chiptype == CHIP_I915) {
if (aperture != (128 * 1024 * 1024) &&
aperture != (256 * 1024 * 1024)) {
printf("agp: bad aperture size %d\n", aperture);
return (EINVAL);
}
- reg = pci_conf_read(isc->bridge_pa.pa_pc,
- isc->bridge_pa.pa_tag, AGP_I915_MSAC);
+ reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_I915_MSAC);
reg &= ~AGP_I915_MSAC_GMASIZE;
if (aperture == (128 * 1024 * 1024))
reg |= AGP_I915_MSAC_GMASIZE_128;
else
reg |= AGP_I915_MSAC_GMASIZE_256;
- pci_conf_write(isc->bridge_pa.pa_pc,
- isc->bridge_pa.pa_tag, AGP_I915_MSAC, reg);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_I915_MSAC, reg);
} else if (isc->chiptype == CHIP_I965) {
- reg = pci_conf_read(isc->bridge_pa.pa_pc,
- isc->bridge_pa.pa_tag, AGP_I965_MSAC);
+ reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_I965_MSAC);
reg &= ~AGP_I965_MSAC_GMASIZE;
switch (aperture) {
case (128 * 1024 * 1024):
@@ -577,8 +598,7 @@ agp_i810_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
printf("agp: bad aperture size %d\n", aperture);
return (EINVAL);
}
- pci_conf_write(isc->bridge_pa.pa_pc,
- isc->bridge_pa.pa_tag, AGP_I965_MSAC, reg);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_I965_MSAC, reg);
} else { /* CHIP_I855 */
if (aperture != (128 * 1024 * 1024)) {
printf("agp: bad aperture size %d\n", aperture);
@@ -590,7 +610,7 @@ agp_i810_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
}
int
-agp_i810_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
+agp_i810_bind_page(struct agp_softc *sc, off_t offset, bus_addr_t physical)
{
struct agp_i810_softc *isc = sc->sc_chipc;
@@ -612,12 +632,12 @@ agp_i810_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
}
}
- WRITE_GATT(offset, physical);
+ WRITEGTT(offset, physical);
return (0);
}
int
-agp_i810_unbind_page(struct vga_pci_softc *sc, off_t offset)
+agp_i810_unbind_page(struct agp_softc *sc, off_t offset)
{
struct agp_i810_softc *isc = sc->sc_chipc;
@@ -633,7 +653,7 @@ agp_i810_unbind_page(struct vga_pci_softc *sc, off_t offset)
}
}
- WRITE_GATT(offset, 0);
+ WRITEGTT(offset, 0);
return (0);
}
@@ -641,25 +661,28 @@ agp_i810_unbind_page(struct vga_pci_softc *sc, off_t offset)
* Writing via memory mapped registers already flushes all TLBs.
*/
void
-agp_i810_flush_tlb(struct vga_pci_softc *sc)
+agp_i810_flush_tlb(struct agp_softc *sc)
{
}
int
-agp_i810_enable(struct vga_pci_softc *sc, u_int32_t mode)
+agp_i810_enable(struct agp_softc *sc, u_int32_t mode)
{
return (0);
}
struct agp_memory *
-agp_i810_alloc_memory(struct vga_pci_softc *sc, int type, vsize_t size)
+agp_i810_alloc_memory(struct agp_softc *sc, int type, vsize_t size)
{
struct agp_i810_softc *isc = sc->sc_chipc;
struct agp_memory *mem;
int error;
if ((size & (AGP_PAGE_SIZE - 1)) != 0)
- return 0;
+ return (0);
+
+ if (sc->sc_allocated + size > sc->sc_maxmem)
+ return (NULL);
if (type == 1) {
/*
@@ -679,7 +702,9 @@ agp_i810_alloc_memory(struct vga_pci_softc *sc, int type, vsize_t size)
}
}
- mem = malloc(sizeof *mem, M_DEVBUF, M_WAITOK | M_ZERO);
+ mem = malloc(sizeof *mem, M_AGP, M_WAITOK | M_ZERO);
+ if (mem == NULL)
+ return (NULL);
mem->am_id = sc->sc_nextid++;
mem->am_size = size;
mem->am_type = type;
@@ -689,25 +714,26 @@ agp_i810_alloc_memory(struct vga_pci_softc *sc, int type, vsize_t size)
* Allocate and wire down the pages now so that we can
* get their physical address.
*/
- mem->am_dmaseg = malloc(sizeof *mem->am_dmaseg, M_DEVBUF,
+ mem->am_dmaseg = malloc(sizeof *mem->am_dmaseg, M_AGP,
M_WAITOK);
if (mem->am_dmaseg == NULL) {
- free(mem, M_DEVBUF);
+ free(mem, M_AGP);
return (NULL);
}
if ((error = agp_alloc_dmamem(sc->sc_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_DEVBUF);
- free(mem, M_DEVBUF);
+ free(mem->am_dmaseg, M_AGP);
+ free(mem, M_AGP);
printf("agp: agp_alloc_dmamem(%d)\n", error);
return (NULL);
}
+ memset(mem->am_virtual, 0, size);
} else if (type != 1) {
if ((error = bus_dmamap_create(sc->sc_dmat, size,
size / PAGE_SIZE + 1, size, 0, BUS_DMA_NOWAIT,
&mem->am_dmamap)) != 0) {
- free(mem, M_DEVBUF);
+ free(mem, M_AGP);
printf("agp: bus_dmamap_create(%d)\n", error);
return (NULL);
}
@@ -720,7 +746,7 @@ agp_i810_alloc_memory(struct vga_pci_softc *sc, int type, vsize_t size)
}
int
-agp_i810_free_memory(struct vga_pci_softc *sc, struct agp_memory *mem)
+agp_i810_free_memory(struct agp_softc *sc, struct agp_memory *mem)
{
if (mem->am_is_bound)
return (EBUSY);
@@ -728,17 +754,17 @@ agp_i810_free_memory(struct vga_pci_softc *sc, struct agp_memory *mem)
if (mem->am_type == 2) {
agp_free_dmamem(sc->sc_dmat, mem->am_size, mem->am_dmamap,
mem->am_virtual, mem->am_dmaseg, mem->am_nseg);
- free(mem->am_dmaseg, M_DEVBUF);
+ free(mem->am_dmaseg, M_AGP);
}
sc->sc_allocated -= mem->am_size;
TAILQ_REMOVE(&sc->sc_memory, mem, am_link);
- free(mem, M_DEVBUF);
+ free(mem, M_AGP);
return (0);
}
int
-agp_i810_bind_memory(struct vga_pci_softc *sc, struct agp_memory *mem,
+agp_i810_bind_memory(struct agp_softc *sc, struct agp_memory *mem,
off_t offset)
{
struct agp_i810_softc *isc = sc->sc_chipc;
@@ -750,6 +776,8 @@ agp_i810_bind_memory(struct vga_pci_softc *sc, struct agp_memory *mem,
* to the GTT through the MMIO window.
* Until the issue is solved, simply restore it.
*/
+
+#if 0
regval = bus_space_read_4(isc->bst, isc->bsh, AGP_I810_PGTBL_CTL);
if (regval != (isc->gatt->ag_physical | 1)) {
#if DEBUG
@@ -759,11 +787,11 @@ agp_i810_bind_memory(struct vga_pci_softc *sc, struct agp_memory *mem,
bus_space_write_4(isc->bst, isc->bsh, AGP_I810_PGTBL_CTL,
isc->gatt->ag_physical | 1);
}
+#endif
+ regval = 0;
if (mem->am_type == 2) {
- for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
- WRITE_GATT(offset + i, mem->am_physical + i);
- }
+ WRITEGTT(offset, mem->am_physical);
mem->am_offset = offset;
mem->am_is_bound = 1;
return (0);
@@ -775,24 +803,20 @@ agp_i810_bind_memory(struct vga_pci_softc *sc, struct agp_memory *mem,
if (isc->chiptype != CHIP_I810)
return (EINVAL);
- for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
- WRITE4(AGP_I810_GTT +
- (u_int32_t)(offset >> AGP_PAGE_SHIFT) * 4, i | 3);
- }
+ for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
+ WRITEGTT(offset, i);
mem->am_is_bound = 1;
return (0);
}
int
-agp_i810_unbind_memory(struct vga_pci_softc *sc, struct agp_memory *mem)
+agp_i810_unbind_memory(struct agp_softc *sc, struct agp_memory *mem)
{
struct agp_i810_softc *isc = sc->sc_chipc;
u_int32_t i;
if (mem->am_type == 2) {
- for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
- WRITE_GATT(mem->am_offset + i, 0);
- }
+ WRITEGTT(mem->am_offset, 0);
mem->am_offset = 0;
mem->am_is_bound = 0;
return (0);
@@ -805,26 +829,7 @@ agp_i810_unbind_memory(struct vga_pci_softc *sc, struct agp_memory *mem)
return (EINVAL);
for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
- WRITE4(AGP_I810_GTT + (i >> AGP_PAGE_SHIFT) * 4, 0);
+ WRITEGTT(i,0);
mem->am_is_bound = 0;
return (0);
}
-
-void
-agp_i810_write_gatt(struct agp_i810_softc *isc, bus_size_t off, u_int32_t v)
-{
- u_int32_t d;
-
-
- d = v | 1;
-
- if (isc->chiptype == CHIP_I915)
- WRITEGTT((u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, v ? d : 0);
- else if (isc->chiptype == CHIP_I965) {
- d |= (v & 0x0000000f00000000ULL) >> 28;
- WRITE4(AGP_I965_GTT +
- (u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, v ? d : 0);
- } else
- WRITE4(AGP_I810_GTT +
- (u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, v ? d : 0);
-}
diff --git a/sys/dev/pci/agp_intel.c b/sys/dev/pci/agp_intel.c
index 722b0f8f982..8b799ef4162 100644
--- a/sys/dev/pci/agp_intel.c
+++ b/sys/dev/pci/agp_intel.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: agp_intel.c,v 1.5 2007/10/06 23:50:54 krw Exp $ */
+/* $OpenBSD: agp_intel.c,v 1.6 2007/11/25 17:11:12 oga Exp $ */
/* $NetBSD: agp_intel.c,v 1.3 2001/09/15 00:25:00 thorpej Exp $ */
/*-
@@ -43,23 +43,32 @@
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
-#include <dev/pci/vga_pcivar.h>
+#include <dev/pci/pcidevs.h>
#include <dev/pci/agpvar.h>
#include <dev/pci/agpreg.h>
#include <machine/bus.h>
struct agp_intel_softc {
- u_int32_t initial_aperture; /* aperture size at startup */
- struct agp_gatt *gatt;
+ u_int32_t initial_aperture; /* aperture size at startup */
+ struct agp_gatt *gatt;
+ struct pci_attach_args vga_pa; /* vga card */
+ u_int aperture_mask;
+ int chiptype;
+#define CHIP_INTEL 0x0
+#define CHIP_I443 0x1
+#define CHIP_I840 0x2
+#define CHIP_I845 0x3
+#define CHIP_I850 0x4
+#define CHIP_I865 0x5
};
-static u_int32_t agp_intel_get_aperture(struct vga_pci_softc *);
-static int agp_intel_set_aperture(struct vga_pci_softc *, u_int32_t);
-static int agp_intel_bind_page(struct vga_pci_softc *, off_t, bus_addr_t);
-static int agp_intel_unbind_page(struct vga_pci_softc *, off_t);
-static void agp_intel_flush_tlb(struct vga_pci_softc *);
+static u_int32_t agp_intel_get_aperture(struct agp_softc *);
+static int agp_intel_set_aperture(struct agp_softc *, u_int32_t);
+static int agp_intel_bind_page(struct agp_softc *, off_t, bus_addr_t);
+static int agp_intel_unbind_page(struct agp_softc *, off_t);
+static void agp_intel_flush_tlb(struct agp_softc *);
struct agp_methods agp_intel_methods = {
agp_intel_get_aperture,
@@ -74,15 +83,34 @@ struct agp_methods agp_intel_methods = {
agp_generic_unbind_memory,
};
+static int
+agp_intel_vgamatch(struct pci_attach_args *pa)
+{
+ switch (PCI_PRODUCT(pa->pa_id)) {
+ case PCI_PRODUCT_INTEL_82855PE_AGP:
+ case PCI_PRODUCT_INTEL_82443LX_AGP:
+ case PCI_PRODUCT_INTEL_82443BX_AGP:
+ case PCI_PRODUCT_INTEL_82440BX_AGP:
+ case PCI_PRODUCT_INTEL_82850_AGP: /* i850/i860 */
+ case PCI_PRODUCT_INTEL_82845_AGP:
+ case PCI_PRODUCT_INTEL_82840_AGP:
+ case PCI_PRODUCT_INTEL_82865_AGP:
+ case PCI_PRODUCT_INTEL_82875P_AGP:
+ return (1);
+ }
+
+ return (0);
+}
+
int
-agp_intel_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
- struct pci_attach_args *pchb_pa)
+agp_intel_attach(struct agp_softc *sc, struct pci_attach_args *pa)
{
struct agp_intel_softc *isc;
struct agp_gatt *gatt;
pcireg_t reg;
+ u_int32_t value;
- isc = malloc(sizeof *isc, M_DEVBUF, M_NOWAIT | M_ZERO);
+ isc = malloc(sizeof *isc, M_AGP, M_NOWAIT | M_ZERO);
if (isc == NULL) {
printf(": can't allocate chipset-specific softc\n");
return (ENOMEM);
@@ -91,13 +119,51 @@ agp_intel_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
sc->sc_methods = &agp_intel_methods;
sc->sc_chipc = isc;
- if (agp_map_aperture(sc, AGP_APBASE, PCI_MAPREG_TYPE_MEM) != 0) {
+ if (pci_find_device(&isc->vga_pa, agp_intel_vgamatch) == 0) {
+ printf(": using generic initialization for Intel AGP\n");
+ printf("agp");
+ isc->chiptype = CHIP_INTEL;
+ }
+
+ pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, &sc->sc_capoff,
+ NULL);
+
+ if (agp_map_aperture(pa, sc, AGP_APBASE, PCI_MAPREG_TYPE_MEM) != 0) {
printf(": can't map aperture\n");
- free(isc, M_DEVBUF);
+ free(isc, M_AGP);
sc->sc_chipc = NULL;
return (ENXIO);
}
+ switch (PCI_PRODUCT(isc->vga_pa.pa_id)) {
+ case PCI_PRODUCT_INTEL_82443LX_AGP:
+ case PCI_PRODUCT_INTEL_82443BX_AGP:
+ case PCI_PRODUCT_INTEL_82440BX_AGP:
+ isc->chiptype = CHIP_I443;
+ break;
+ case PCI_PRODUCT_INTEL_82840_AGP:
+ isc->chiptype = CHIP_I840;
+ break;
+ case PCI_PRODUCT_INTEL_82855PE_AGP:
+ case PCI_PRODUCT_INTEL_82845_AGP:
+ isc->chiptype = CHIP_I845;
+ break;
+ case PCI_PRODUCT_INTEL_82850_AGP:
+ isc->chiptype = CHIP_I850;
+ break;
+ case PCI_PRODUCT_INTEL_82865_AGP:
+ case PCI_PRODUCT_INTEL_82875P_AGP:
+ isc->chiptype = CHIP_I865;
+ break;
+ }
+
+ /* Determine maximum supported aperture size. */
+ value = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_APSIZE);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag,
+ AGP_INTEL_APSIZE, APSIZE_MASK);
+ isc->aperture_mask = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
+ AGP_INTEL_APSIZE) & APSIZE_MASK;
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_APSIZE, value);
isc->initial_aperture = AGP_GET_APERTURE(sc);
for (;;) {
@@ -121,25 +187,74 @@ agp_intel_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_ATTBASE,
gatt->ag_physical);
+ /* Enable the GLTB and setup the control register. */
+ switch (isc->chiptype) {
+ case CHIP_I443:
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_AGPCTRL,
+ AGPCTRL_AGPRSE | AGPCTRL_GTLB);
+
+ default:
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_AGPCTRL,
+ pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_AGPCTRL)
+ | AGPCTRL_GTLB);
+ }
+
/* Enable things, clear errors etc. */
- /* XXXfvdl get rid of the magic constants */
- pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_AGPCTRL, 0x2280);
- reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_NBXCFG);
- reg &= ~(1 << 10);
- reg |= (1 << 9);
- pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_NBXCFG, reg);
+ switch (isc->chiptype) {
+ case CHIP_I845:
+ case CHIP_I865:
+ {
+ reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_I840_MCHCFG);
+ reg |= MCHCFG_AAGN;
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_I840_MCHCFG, reg);
+ break;
+ }
+ case CHIP_I840:
+ case CHIP_I850:
+ {
+ reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_AGPCMD);
+ reg |= AGPCMD_AGPEN;
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_AGPCMD,
+ reg);
+ reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_I840_MCHCFG);
+ reg |= MCHCFG_AAGN;
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_I840_MCHCFG,
+ reg);
+ break;
+ }
+ default:
+ {
+ reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_NBXCFG);
+ reg &= ~NBXCFG_APAE;
+ reg |= NBXCFG_AAGN;
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_NBXCFG, reg);
+ }
+ }
- reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_STS);
- reg &= ~0x00ff0000;
- reg |= (7 << 16);
- pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_STS, reg);
+ /* Clear Error status */
+ switch (isc->chiptype) {
+ case CHIP_I840:
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag,
+ AGP_INTEL_I8XX_ERRSTS, 0xc000);
+ break;
+ case CHIP_I845:
+ case CHIP_I850:
+ case CHIP_I865:
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag,
+ AGP_INTEL_I8XX_ERRSTS, 0x00ff);
+ break;
+
+ default:
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag,
+ AGP_INTEL_ERRSTS, 0x70);
+ }
return (0);
}
#if 0
static int
-agp_intel_detach(struct vga_pci_softc *sc)
+agp_intel_detach(struct agp_softc *sc)
{
int error;
pcireg_t reg;
@@ -149,6 +264,7 @@ agp_intel_detach(struct vga_pci_softc *sc)
if (error)
return (error);
+ /* XXX i845/i855PM/i840/i850E */
reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_NBXCFG);
reg &= ~(1 << 9);
printf("%s: set NBXCFG to %x\n", __FUNCTION__, reg);
@@ -162,12 +278,13 @@ agp_intel_detach(struct vga_pci_softc *sc)
#endif
static u_int32_t
-agp_intel_get_aperture(struct vga_pci_softc *sc)
+agp_intel_get_aperture(struct agp_softc *sc)
{
+ struct agp_intel_softc *isc = sc->sc_chipc;
u_int32_t apsize;
apsize = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
- AGP_INTEL_APSIZE) & 0x1f;
+ AGP_INTEL_APSIZE) & isc->aperture_mask;
/*
* The size is determined by the number of low bits of
@@ -176,35 +293,34 @@ agp_intel_get_aperture(struct vga_pci_softc *sc)
* field just read forces the corresponding bit in the 27:22
* to be zero. We calculate the aperture size accordingly.
*/
- return ((((apsize ^ 0x1f) << 22) | ((1 << 22) - 1)) + 1);
+ return ((((apsize ^ isc->aperture_mask) << 22) | ((1 << 22) - 1)) + 1);
}
static int
-agp_intel_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
+agp_intel_set_aperture(struct agp_softc *sc, u_int32_t aperture)
{
+ struct agp_intel_softc *isc = sc->sc_chipc;
u_int32_t apsize;
- pcireg_t reg;
/*
* Reverse the magic from get_aperture.
*/
- apsize = ((aperture - 1) >> 22) ^ 0x1f;
+ apsize = ((aperture - 1) >> 22) ^ isc->aperture_mask;
/*
* Double check for sanity.
*/
- if ((((apsize ^ 0x1f) << 22) | ((1 << 22) - 1)) + 1 != aperture)
+ if ((((apsize ^ isc->aperture_mask) << 22) |
+ ((1 << 22) - 1)) + 1 != aperture)
return (EINVAL);
- reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_APSIZE);
- reg = (reg & 0xffffff00) | apsize;
- pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_APSIZE, reg);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_APSIZE, apsize);
return (0);
}
static int
-agp_intel_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
+agp_intel_bind_page(struct agp_softc *sc, off_t offset, bus_addr_t physical)
{
struct agp_intel_softc *isc = sc->sc_chipc;
@@ -216,7 +332,7 @@ agp_intel_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
}
static int
-agp_intel_unbind_page(struct vga_pci_softc *sc, off_t offset)
+agp_intel_unbind_page(struct agp_softc *sc, off_t offset)
{
struct agp_intel_softc *isc = sc->sc_chipc;
@@ -228,8 +344,32 @@ agp_intel_unbind_page(struct vga_pci_softc *sc, off_t offset)
}
static void
-agp_intel_flush_tlb(struct vga_pci_softc *sc)
+agp_intel_flush_tlb(struct agp_softc *sc)
{
- pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_AGPCTRL, 0x2200);
- pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_AGPCTRL, 0x2280);
+ struct agp_intel_softc *isc = sc->sc_chipc;
+ pcireg_t reg;
+
+ switch (isc->chiptype) {
+ case CHIP_I865:
+ case CHIP_I850:
+ case CHIP_I845:
+ case CHIP_I840:
+ case CHIP_I443:
+ {
+ reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_AGPCTRL);
+ reg &= ~AGPCTRL_GTLB;
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_AGPCTRL,
+ reg);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_AGPCTRL,
+ reg | AGPCTRL_GTLB);
+ break;
+ }
+ default: /* XXX */
+ {
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_AGPCTRL,
+ 0x2200);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_INTEL_AGPCTRL,
+ 0x2280);
+ }
+ }
}
diff --git a/sys/dev/pci/agp_sis.c b/sys/dev/pci/agp_sis.c
index 31ef1591fe9..41d68b1552e 100644
--- a/sys/dev/pci/agp_sis.c
+++ b/sys/dev/pci/agp_sis.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: agp_sis.c,v 1.3 2007/08/04 19:40:25 reyk Exp $ */
+/* $OpenBSD: agp_sis.c,v 1.4 2007/11/25 17:11:12 oga Exp $ */
/* $NetBSD: agp_sis.c,v 1.2 2001/09/15 00:25:00 thorpej Exp $ */
/*-
@@ -53,11 +53,11 @@ struct agp_sis_softc {
struct agp_gatt *gatt;
};
-static u_int32_t agp_sis_get_aperture(struct vga_pci_softc *);
-static int agp_sis_set_aperture(struct vga_pci_softc *, u_int32_t);
-static int agp_sis_bind_page(struct vga_pci_softc *, off_t, bus_addr_t);
-static int agp_sis_unbind_page(struct vga_pci_softc *, off_t);
-static void agp_sis_flush_tlb(struct vga_pci_softc *);
+static u_int32_t agp_sis_get_aperture(struct agp_softc *);
+static int agp_sis_set_aperture(struct agp_softc *, u_int32_t);
+static int agp_sis_bind_page(struct agp_softc *, off_t, bus_addr_t);
+static int agp_sis_unbind_page(struct agp_softc *, off_t);
+static void agp_sis_flush_tlb(struct agp_softc *);
struct agp_methods agp_sis_methods = {
agp_sis_get_aperture,
@@ -74,14 +74,13 @@ struct agp_methods agp_sis_methods = {
int
-agp_sis_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
- struct pci_attach_args *pchb_pa)
+agp_sis_attach(struct agp_softc *sc, struct pci_attach_args *pa)
{
struct agp_sis_softc *ssc;
struct agp_gatt *gatt;
pcireg_t reg;
- ssc = malloc(sizeof *ssc, M_DEVBUF, M_NOWAIT);
+ ssc = malloc(sizeof *ssc, M_AGP, M_NOWAIT);
if (ssc == NULL) {
printf(": can't allocate chipset-specific softc\n");
return (ENOMEM);
@@ -89,9 +88,9 @@ agp_sis_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
sc->sc_methods = &agp_sis_methods;
sc->sc_chipc = ssc;
- if (agp_map_aperture(sc, AGP_APBASE, PCI_MAPREG_TYPE_MEM) != 0) {
+ if (agp_map_aperture(pa, sc, AGP_APBASE, PCI_MAPREG_TYPE_MEM) != 0) {
printf(": can't map aperture\n");
- free(ssc, M_DEVBUF);
+ free(ssc, M_AGP);
return (ENXIO);
}
@@ -128,7 +127,7 @@ agp_sis_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
#if 0
static int
-agp_sis_detach(struct vga_pci_softc *sc)
+agp_sis_detach(struct agp_softc *sc)
{
struct agp_sis_softc *ssc = sc->sc_chipc;
pcireg_t reg;
@@ -152,7 +151,7 @@ agp_sis_detach(struct vga_pci_softc *sc)
#endif
static u_int32_t
-agp_sis_get_aperture(struct vga_pci_softc *sc)
+agp_sis_get_aperture(struct agp_softc *sc)
{
int gws;
@@ -165,7 +164,7 @@ agp_sis_get_aperture(struct vga_pci_softc *sc)
}
static int
-agp_sis_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
+agp_sis_set_aperture(struct agp_softc *sc, u_int32_t aperture)
{
int gws;
pcireg_t reg;
@@ -190,7 +189,7 @@ agp_sis_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
}
static int
-agp_sis_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
+agp_sis_bind_page(struct agp_softc *sc, off_t offset, bus_addr_t physical)
{
struct agp_sis_softc *ssc = sc->sc_chipc;
@@ -202,7 +201,7 @@ agp_sis_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
}
static int
-agp_sis_unbind_page(struct vga_pci_softc *sc, off_t offset)
+agp_sis_unbind_page(struct agp_softc *sc, off_t offset)
{
struct agp_sis_softc *ssc = sc->sc_chipc;
@@ -214,7 +213,7 @@ agp_sis_unbind_page(struct vga_pci_softc *sc, off_t offset)
}
static void
-agp_sis_flush_tlb(struct vga_pci_softc *sc)
+agp_sis_flush_tlb(struct agp_softc *sc)
{
pcireg_t reg;
diff --git a/sys/dev/pci/agp_via.c b/sys/dev/pci/agp_via.c
index bb9c0114699..f5007bae856 100644
--- a/sys/dev/pci/agp_via.c
+++ b/sys/dev/pci/agp_via.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: agp_via.c,v 1.4 2007/10/06 23:50:54 krw Exp $ */
+/* $OpenBSD: agp_via.c,v 1.5 2007/11/25 17:11:12 oga Exp $ */
/* $NetBSD: agp_via.c,v 1.2 2001/09/15 00:25:00 thorpej Exp $ */
/*-
@@ -48,11 +48,11 @@
#include <machine/bus.h>
-static u_int32_t agp_via_get_aperture(struct vga_pci_softc *);
-static int agp_via_set_aperture(struct vga_pci_softc *, u_int32_t);
-static int agp_via_bind_page(struct vga_pci_softc *, off_t, bus_addr_t);
-static int agp_via_unbind_page(struct vga_pci_softc *, off_t);
-static void agp_via_flush_tlb(struct vga_pci_softc *);
+static u_int32_t agp_via_get_aperture(struct agp_softc *);
+static int agp_via_set_aperture(struct agp_softc *, u_int32_t);
+static int agp_via_bind_page(struct agp_softc *, off_t, bus_addr_t);
+static int agp_via_unbind_page(struct agp_softc *, off_t);
+static void agp_via_flush_tlb(struct agp_softc *);
struct agp_methods agp_via_methods = {
agp_via_get_aperture,
@@ -70,27 +70,52 @@ struct agp_methods agp_via_methods = {
struct agp_via_softc {
u_int32_t initial_aperture; /* aperture size at startup */
struct agp_gatt *gatt;
+ int *regs;
};
+#define REG_GARTCTRL 0
+#define REG_APSIZE 1
+#define REG_ATTBASE 2
+
+int via_v2_regs[] =
+ { AGP_VIA_GARTCTRL, AGP_VIA_APSIZE, AGP_VIA_ATTBASE };
+int via_v3_regs[] =
+ { AGP3_VIA_GARTCTRL, AGP3_VIA_APSIZE, AGP3_VIA_ATTBASE };
int
-agp_via_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
- struct pci_attach_args *pchb_pa)
+agp_via_attach(struct agp_softc *sc, struct pci_attach_args *pa)
{
struct agp_via_softc *asc;
struct agp_gatt *gatt;
+ pcireg_t agpsel, capval;
- asc = malloc(sizeof *asc, M_DEVBUF, M_NOWAIT | M_ZERO);
+ asc = malloc(sizeof *asc, M_AGP, M_NOWAIT | M_ZERO);
if (asc == NULL) {
printf(": can't allocate chipset-specific softc\n");
return (ENOMEM);
}
sc->sc_chipc = asc;
sc->sc_methods = &agp_via_methods;
+ pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, &sc->sc_capoff,
+ &capval);
+
+ if (AGP_CAPID_GET_MAJOR(capval) >= 3) {
+ agpsel = pci_conf_read(pa->pa_pc, pa->pa_tag, AGP_VIA_AGPSEL);
+ if ((agpsel & (1 << 1)) == 0) {
+ asc->regs = via_v3_regs;
+ printf(" (v3)");
+ } else {
+ asc->regs = via_v2_regs;
+ printf(" (v2 compat mode)");
+ }
+ } else {
+ asc->regs = via_v2_regs;
+ printf(" (v2)");
+ }
- if (agp_map_aperture(sc, AGP_APBASE, PCI_MAPREG_TYPE_MEM) != 0) {
+ if (agp_map_aperture(pa ,sc, AGP_APBASE, PCI_MAPREG_TYPE_MEM) != 0) {
printf(": can't map aperture\n");
- free(asc, M_DEVBUF);
+ free(asc, M_AGP);
return (ENXIO);
}
@@ -113,19 +138,31 @@ agp_via_attach(struct vga_pci_softc *sc, struct pci_attach_args *pa,
}
asc->gatt = gatt;
- /* Install the gatt. */
- pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_ATTBASE,
- gatt->ag_physical | 3);
-
- /* Enable the aperture. */
- pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_GARTCTRL, 0x0000000f);
+ if (asc->regs == via_v2_regs) {
+ /* Install the gatt. */
+ pci_conf_write(pa->pa_pc, pa->pa_tag, asc->regs[REG_ATTBASE],
+ gatt->ag_physical | 3);
+ /* Enable the aperture. */
+ pci_conf_write(pa->pa_pc, pa->pa_tag, asc->regs[REG_GARTCTRL],
+ 0x0000000f);
+ } else {
+ pcireg_t gartctrl;
+ /* Install the gatt. */
+ pci_conf_write(pa->pa_pc, pa->pa_tag, asc->regs[REG_ATTBASE],
+ gatt->ag_physical);
+ /* Enable the aperture. */
+ gartctrl = pci_conf_read(pa->pa_pc, pa->pa_tag,
+ asc->regs[REG_ATTBASE]);
+ pci_conf_write(pa->pa_pc, pa->pa_tag, asc->regs[REG_GARTCTRL],
+ gartctrl | (3 << 7));
+ }
return (0);
}
#if 0
static int
-agp_via_detach(struct vga_pci_softc *sc)
+agp_via_detach(struct agp_softc *sc)
{
struct agp_via_softc *asc = sc->sc_chipc;
int error;
@@ -134,8 +171,8 @@ agp_via_detach(struct vga_pci_softc *sc)
if (error)
return (error);
- pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_GARTCTRL, 0);
- pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_ATTBASE, 0);
+ pci_conf_write(sc->as_pc, sc->as_tag, asc->regs[REG_GARTCTRL], 0);
+ pci_conf_write(sc->as_pc, sc->as_tag, asc->regs[REG_ATTBASE], 0);
AGP_SET_APERTURE(sc, asc->initial_aperture);
agp_free_gatt(sc, asc->gatt);
@@ -144,12 +181,13 @@ agp_via_detach(struct vga_pci_softc *sc)
#endif
static u_int32_t
-agp_via_get_aperture(struct vga_pci_softc *sc)
+agp_via_get_aperture(struct agp_softc *sc)
{
+ struct agp_via_softc *asc = sc->sc_chipc;
u_int32_t apsize;
- apsize = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
- AGP_VIA_APSIZE) & 0x1f;
+ apsize = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
+ asc->regs[REG_APSIZE]) & 0x1f;
/*
* The size is determined by the number of low bits of
@@ -162,8 +200,9 @@ agp_via_get_aperture(struct vga_pci_softc *sc)
}
static int
-agp_via_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
+agp_via_set_aperture(struct agp_softc *sc, u_int32_t aperture)
{
+ struct agp_via_softc *asc = sc->sc_chipc;
u_int32_t apsize;
pcireg_t reg;
@@ -178,16 +217,16 @@ agp_via_set_aperture(struct vga_pci_softc *sc, u_int32_t aperture)
if ((((apsize ^ 0xff) << 20) | ((1 << 20) - 1)) + 1 != aperture)
return (EINVAL);
- reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, AGP_VIA_APSIZE);
+ reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, asc->regs[REG_APSIZE]);
reg &= ~0xff;
reg |= apsize;
- pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_APSIZE, reg);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, asc->regs[REG_APSIZE], reg);
return (0);
}
static int
-agp_via_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
+agp_via_bind_page(struct agp_softc *sc, off_t offset, bus_addr_t physical)
{
struct agp_via_softc *asc = sc->sc_chipc;
@@ -199,7 +238,7 @@ agp_via_bind_page(struct vga_pci_softc *sc, off_t offset, bus_addr_t physical)
}
static int
-agp_via_unbind_page(struct vga_pci_softc *sc, off_t offset)
+agp_via_unbind_page(struct agp_softc *sc, off_t offset)
{
struct agp_via_softc *asc = sc->sc_chipc;
@@ -211,8 +250,22 @@ agp_via_unbind_page(struct vga_pci_softc *sc, off_t offset)
}
static void
-agp_via_flush_tlb(struct vga_pci_softc *sc)
+agp_via_flush_tlb(struct agp_softc *sc)
{
- pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_GARTCTRL, 0x8f);
- pci_conf_write(sc->sc_pc, sc->sc_pcitag, AGP_VIA_GARTCTRL, 0x0f);
+ struct agp_via_softc *asc = sc->sc_chipc;
+ pcireg_t gartctrl;
+
+ if (asc->regs == via_v2_regs) {
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, asc->regs[REG_GARTCTRL],
+ 0x8f);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, asc->regs[REG_GARTCTRL],
+ 0x0f);
+ } else {
+ gartctrl = pci_conf_read(sc->sc_pc, sc->sc_pcitag,
+ asc->regs[REG_GARTCTRL]);
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, asc->regs[REG_GARTCTRL],
+ gartctrl & ~(1 << 7));
+ pci_conf_write(sc->sc_pc, sc->sc_pcitag, asc->regs[REG_GARTCTRL],
+ gartctrl);
+ }
}
diff --git a/sys/dev/pci/agpreg.h b/sys/dev/pci/agpreg.h
index 2e3c87a61b3..8ae675f083d 100644
--- a/sys/dev/pci/agpreg.h
+++ b/sys/dev/pci/agpreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: agpreg.h,v 1.7 2007/08/04 19:40:25 reyk Exp $ */
+/* $OpenBSD: agpreg.h,v 1.8 2007/11/25 17:11:12 oga Exp $ */
/* $NetBSD: agpreg.h,v 1.1 2001/09/10 10:01:02 fvdl Exp $ */
/*-
@@ -52,20 +52,58 @@
/*
* Config offsets for Intel AGP chipsets.
*/
+/* i845/855PM */
+#define AGP_I845_AGPMISC 0x51
+#define AGPMISC_AAGN (1U << 1) /* Aperture AccessEN */
+
+/* i840/850/850E */
+#define AGP_I840_MCHCFG 0x50
+#define MCHCFG_AAGN (1U << 9) /* Aperture AccessEN */
+
+/* i82443LX/BX/GX */
#define AGP_INTEL_NBXCFG 0x50
#define AGP_INTEL_STS 0x90
+#define NBXCFG_APAE (1U << 10) /* AGPtoPCI AccessDIS */
+#define NBXCFG_AAGN (1U << 9) /* Aperture AccessEN */
+
+/* Error Status for i8XX Chipset */
+#define AGP_INTEL_I8XX_ERRSTS 0xc8
+
+/* Common register */
+#define AGP_INTEL_ERRSTS 0x91 /* Not i8XX */
+#define AGP_INTEL_AGPCMD 0xa8
+#define AGPCMD_SBA (1U << 9)
+#define AGPCMD_AGPEN (1U << 8)
+#define AGPCMD_FWEN (1U << 4)
+#define AGPCMD_RATE_1X (1U << 1)
+#define AGPCMD_RATE_2X (1U << 2)
+#define AGPCMD_RATE_4X (1U << 3)
+
#define AGP_INTEL_AGPCTRL 0xb0
+#define AGPCTRL_AGPRSE (1U << 13) /* AGPRSE (82443 only)*/
+#define AGPCTRL_GTLB (1U << 7) /* GTLB EN */
+
#define AGP_INTEL_APSIZE 0xb4
+#define APSIZE_MASK 0x3f
+
#define AGP_INTEL_ATTBASE 0xb8
/*
- * Config offsets for VIA AGP chipsets.
+ * Config offsets for VIA AGP 2.x chipsets.
*/
#define AGP_VIA_GARTCTRL 0x80
#define AGP_VIA_APSIZE 0x84
#define AGP_VIA_ATTBASE 0x88
/*
+ * Config offsets for VIA AGP 3.0 chipsets.
+ */
+#define AGP3_VIA_GARTCTRL 0x90
+#define AGP3_VIA_APSIZE 0x94
+#define AGP3_VIA_ATTBASE 0x98
+#define AGP_VIA_AGPSEL 0xfd
+
+/*
* Config offsets for SiS AGP chipsets.
*/
#define AGP_SIS_ATTBASE 0x90
diff --git a/sys/dev/pci/agpvar.h b/sys/dev/pci/agpvar.h
index 4b602253cf1..ee16085b077 100644
--- a/sys/dev/pci/agpvar.h
+++ b/sys/dev/pci/agpvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: agpvar.h,v 1.6 2007/08/04 19:40:25 reyk Exp $ */
+/* $OpenBSD: agpvar.h,v 1.7 2007/11/25 17:11:12 oga Exp $ */
/* $NetBSD: agpvar.h,v 1.4 2001/10/01 21:54:48 fvdl Exp $ */
/*-
@@ -33,7 +33,6 @@
#define _PCI_AGPVAR_H_
#include <sys/lock.h>
-#include <dev/pci/vga_pcivar.h>
/* #define AGP_DEBUG */
#ifdef AGP_DEBUG
@@ -44,19 +43,69 @@
#define AGPUNIT(x) minor(x)
+struct agpbus_attach_args {
+ char *apa_busname;
+ struct pci_attach_args apa_pci_args;
+};
+
+enum agp_acquire_state {
+ AGP_ACQUIRE_FREE,
+ AGP_ACQUIRE_USER,
+ AGP_ACQUIRE_KERNEL
+};
+
+/*
+ * Data structure to describe an AGP memory allocation.
+ */
+TAILQ_HEAD(agp_memory_list, agp_memory);
+struct agp_memory {
+ TAILQ_ENTRY(agp_memory) am_link; /* wiring for the tailq */
+ int am_id; /* unique id for block */
+ vsize_t am_size; /* number of bytes allocated */
+ int am_type; /* chipset specific type */
+ off_t am_offset; /* page offset if bound */
+ int am_is_bound; /* non-zero if bound */
+ bus_addr_t am_physical;
+ caddr_t am_virtual;
+ bus_dmamap_t am_dmamap;
+ int am_nseg;
+ bus_dma_segment_t *am_dmaseg;
+};
+
+/*
+ * This structure is used to query the state of the AGP system.
+ */
+struct agp_info {
+ u_int32_t ai_mode;
+ bus_addr_t ai_aperture_base;
+ bus_size_t ai_aperture_size;
+ vsize_t ai_memory_allowed;
+ vsize_t ai_memory_used;
+ u_int32_t ai_devid;
+};
+
+struct agp_memory_info {
+ vsize_t ami_size; /* size in bytes */
+ bus_addr_t ami_physical; /* bogus hack for i810 */
+ off_t ami_offset; /* page offset if bound */
+ int ami_is_bound; /* non-zero if bound */
+};
+
+struct agp_softc;
+
struct agp_methods {
- u_int32_t (*get_aperture)(struct vga_pci_softc *);
- int (*set_aperture)(struct vga_pci_softc *, u_int32_t);
- int (*bind_page)(struct vga_pci_softc *, off_t, bus_addr_t);
- int (*unbind_page)(struct vga_pci_softc *, off_t);
- void (*flush_tlb)(struct vga_pci_softc *);
- int (*enable)(struct vga_pci_softc *, u_int32_t mode);
+ u_int32_t (*get_aperture)(struct agp_softc *);
+ int (*set_aperture)(struct agp_softc *, u_int32_t);
+ int (*bind_page)(struct agp_softc *, off_t, bus_addr_t);
+ int (*unbind_page)(struct agp_softc *, off_t);
+ void (*flush_tlb)(struct agp_softc *);
+ int (*enable)(struct agp_softc *, u_int32_t mode);
struct agp_memory *
- (*alloc_memory)(struct vga_pci_softc *, int, vsize_t);
- int (*free_memory)(struct vga_pci_softc *, struct agp_memory *);
- int (*bind_memory)(struct vga_pci_softc *, struct agp_memory *,
+ (*alloc_memory)(struct agp_softc *, int, vsize_t);
+ int (*free_memory)(struct agp_softc *, struct agp_memory *);
+ int (*bind_memory)(struct agp_softc *, struct agp_memory *,
off_t);
- int (*unbind_memory)(struct vga_pci_softc *, struct agp_memory *);
+ int (*unbind_memory)(struct agp_softc *, struct agp_memory *);
};
#define AGP_GET_APERTURE(sc) ((sc)->sc_methods->get_aperture(sc))
@@ -73,6 +122,32 @@ struct agp_methods {
/*
* All chipset drivers must have this at the start of their softc.
*/
+struct agp_softc {
+ struct device sc_dev;
+
+ bus_space_tag_t sc_bt, sc_memt;
+ bus_space_handle_t sc_bh;
+ bus_addr_t sc_apaddr;
+ bus_size_t sc_apsize;
+ bus_dma_tag_t sc_dmat;
+ struct lock sc_lock; /* lock for access to GATT */
+ pcitag_t sc_pcitag; /* PCI tag, in case we need it. */
+ pcireg_t sc_id;
+ pci_chipset_tag_t sc_pc;
+
+ struct agp_methods *sc_methods;
+ void *sc_chipc; /* chipset-dependent state */
+
+ int sc_opened;
+ int sc_capoff;
+ int sc_apflags;
+ int sc_nextid; /* next memory block id */
+
+ u_int32_t sc_maxmem; /* allocation upper bound */
+ u_int32_t sc_allocated; /* amount allocated */
+ enum agp_acquire_state sc_state;
+ struct agp_memory_list sc_memory; /* list of allocated memory */
+};
struct agp_gatt {
u_int32_t ag_entries;
@@ -84,42 +159,119 @@ struct agp_gatt {
};
+struct agp_product {
+ int ap_vendor;
+ int ap_product;
+ int (*ap_attach)(struct agp_softc *,
+ struct pci_attach_args *);
+};
+/* MD-defined */
+extern const struct agp_product agp_products[];
+
+void agp_attach(struct device *, struct device *, void *);
+paddr_t agpmmap(void *, off_t, int);
+int agpioctl(dev_t, u_long, caddr_t, int, struct proc *);
+int agpopen(dev_t, int, int, struct proc *);
+int agpclose(dev_t, int, int , struct proc *);
/*
* Functions private to the AGP code.
*/
int agp_find_caps(pci_chipset_tag_t, pcitag_t);
-int agp_map_aperture(struct vga_pci_softc *, u_int32_t, u_int32_t);
+int
+agp_map_aperture(struct pci_attach_args *, struct agp_softc *,
+ u_int32_t, u_int32_t);
struct agp_gatt *
- agp_alloc_gatt(struct vga_pci_softc *);
-void agp_free_gatt(struct vga_pci_softc *, struct agp_gatt *);
+ agp_alloc_gatt(struct agp_softc *);
+void agp_free_gatt(struct agp_softc *, struct agp_gatt *);
void agp_flush_cache(void);
-int agp_generic_attach(struct vga_pci_softc *);
-int agp_generic_detach(struct vga_pci_softc *);
-int agp_generic_enable(struct vga_pci_softc *, u_int32_t);
+int agp_generic_attach(struct agp_softc *);
+int agp_generic_detach(struct agp_softc *);
+int agp_generic_enable(struct agp_softc *, u_int32_t);
struct agp_memory *
- agp_generic_alloc_memory(struct vga_pci_softc *, int, vsize_t size);
-int agp_generic_free_memory(struct vga_pci_softc *, struct agp_memory *);
-int agp_generic_bind_memory(struct vga_pci_softc *, struct agp_memory *,
+ agp_generic_alloc_memory(struct agp_softc *, int, vsize_t size);
+int agp_generic_free_memory(struct agp_softc *, struct agp_memory *);
+int agp_generic_bind_memory(struct agp_softc *, struct agp_memory *,
off_t);
-int agp_generic_unbind_memory(struct vga_pci_softc *, struct agp_memory *);
-
-int agp_ali_attach(struct vga_pci_softc *, struct pci_attach_args *,
- struct pci_attach_args *);
-int agp_amd_attach(struct vga_pci_softc *, struct pci_attach_args *,
- struct pci_attach_args *);
-int agp_i810_attach(struct vga_pci_softc *, struct pci_attach_args *,
- struct pci_attach_args *);
-int agp_intel_attach(struct vga_pci_softc *, struct pci_attach_args *,
- struct pci_attach_args *);
-int agp_via_attach(struct vga_pci_softc *, struct pci_attach_args *,
- struct pci_attach_args *);
-int agp_sis_attach(struct vga_pci_softc *, struct pci_attach_args *,
- struct pci_attach_args *);
+int agp_generic_unbind_memory(struct agp_softc *, struct agp_memory *);
+
+int agp_ali_attach(struct agp_softc *, struct pci_attach_args *);
+int agp_amd_attach(struct agp_softc *, struct pci_attach_args *);
+int agp_i810_attach(struct agp_softc *, struct pci_attach_args *);
+int agp_intel_attach(struct agp_softc *, struct pci_attach_args *);
+int agp_via_attach(struct agp_softc *, struct pci_attach_args *);
+int agp_sis_attach(struct agp_softc *, struct pci_attach_args *);
int agp_alloc_dmamem(bus_dma_tag_t, size_t, int, bus_dmamap_t *,
caddr_t *, bus_addr_t *, bus_dma_segment_t *, int, int *);
void agp_free_dmamem(bus_dma_tag_t, size_t, bus_dmamap_t,
caddr_t, bus_dma_segment_t *, int nseg) ;
+
+/*
+ * Kernel API
+ */
+/*
+ * Find the AGP device and return it.
+ */
+void *agp_find_device(int);
+
+/*
+ * Return the current owner of the AGP chipset.
+ */
+enum agp_acquire_state agp_state(void *);
+
+/*
+ * Query the state of the AGP system.
+ */
+void agp_get_info(void *, struct agp_info *);
+
+/*
+ * Acquire the AGP chipset for use by the kernel. Returns EBUSY if the
+ * AGP chipset is already acquired by another user.
+ */
+int agp_acquire(void *);
+
+/*
+ * Release the AGP chipset.
+ */
+int agp_release(void *);
+
+/*
+ * Enable the agp hardware with the relavent mode. The mode bits are
+ * defined in <dev/pci/agpreg.h>
+ */
+int agp_enable(void *, u_int32_t);
+
+/*
+ * Allocate physical memory suitable for mapping into the AGP
+ * aperture. The value returned is an opaque handle which can be
+ * passed to agp_bind(), agp_unbind() or agp_deallocate().
+ */
+void *agp_alloc_memory(void *, int, vsize_t);
+
+/*
+ * Free memory which was allocated with agp_allocate().
+ */
+void agp_free_memory(void *, void *);
+
+/*
+ * Bind memory allocated with agp_allocate() at a given offset within
+ * the AGP aperture. Returns EINVAL if the memory is already bound or
+ * the offset is not at an AGP page boundary.
+ */
+int agp_bind_memory(void *, void *, off_t);
+
+/*
+ * Unbind memory from the AGP aperture. Returns EINVAL if the memory
+ * is not bound.
+ */
+int agp_unbind_memory(void *, void *);
+
+/*
+ * Retrieve information about a memory block allocated with
+ * agp_alloc_memory().
+ */
+void agp_memory_info(void *, void *, struct agp_memory_info *);
+
#endif /* !_PCI_AGPVAR_H_ */
diff --git a/sys/dev/pci/files.agp b/sys/dev/pci/files.agp
new file mode 100644
index 00000000000..e1b5249e1f3
--- /dev/null
+++ b/sys/dev/pci/files.agp
@@ -0,0 +1,31 @@
+# $OpenBSD: files.agp,v 1.1 2007/11/25 17:11:12 oga Exp $
+
+define agpbus { }
+
+device agp
+attach agp at agpbus
+file dev/pci/agp.c agp needs-flag
+
+define agp_ali
+file dev/pci/agp_ali.c agp_ali & agp needs-flag
+
+define agp_amd
+file dev/pci/agp_amd.c agp_amd & agp needs-flag
+
+define agp_apple
+file dev/pci/agp_apple.c agp_apple & agp needs-flag
+
+define agp_i810
+file dev/pci/agp_i810.c agp_i810 & agp needs-flag
+
+define agp_intel
+file dev/pci/agp_intel.c agp_intel & agp needs-flag
+
+define agp_sis
+file dev/pci/agp_sis.c agp_sis & agp needs-flag
+
+define agp_via
+file dev/pci/agp_via.c agp_via & agp needs-flag
+
+define agp_amd64
+file dev/pci/agp_amd64.c agp_amd64 & agp needs-flag
diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci
index 8ace3b57bd0..af39d55c8c5 100644
--- a/sys/dev/pci/files.pci
+++ b/sys/dev/pci/files.pci
@@ -1,4 +1,4 @@
-# $OpenBSD: files.pci,v 1.247 2007/10/30 12:31:06 jsg Exp $
+# $OpenBSD: files.pci,v 1.248 2007/11/25 17:11:12 oga Exp $
# $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $
#
# Config file and device description for machine-independent PCI code.
@@ -15,7 +15,6 @@ file dev/pci/pci_subr.c pci
# Generic VGA
attach vga at pci with vga_pci
file dev/pci/vga_pci.c vga_pci
-file dev/pci/agp.c vga_pci & pciagp
device tga: wsemuldisplaydev, rasops8, rasops32
attach tga at pci
diff --git a/sys/dev/pci/vga_pci.c b/sys/dev/pci/vga_pci.c
index fc4c4507632..2535be4ead7 100644
--- a/sys/dev/pci/vga_pci.c
+++ b/sys/dev/pci/vga_pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vga_pci.c,v 1.27 2007/11/03 10:09:03 martin Exp $ */
+/* $OpenBSD: vga_pci.c,v 1.28 2007/11/25 17:11:12 oga Exp $ */
/* $NetBSD: vga_pci.c,v 1.3 1998/06/08 06:55:58 thorpej Exp $ */
/*
@@ -149,9 +149,6 @@ vga_pci_attach(struct device *parent, struct device *self, void *aux)
reg |= PCI_COMMAND_MASTER_ENABLE;
pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, reg);
-#ifdef PCIAGP
- agp_attach(parent, self, aux);
-#endif
#ifdef VESAFB
if (vesabios_softc != NULL && vesabios_softc->sc_nmodes > 0) {
sc->sc_textmode = vesafb_get_mode(sc);
@@ -179,11 +176,7 @@ vga_pci_mmap(void *v, off_t off, int prot)
return atop(sc->sc_base + off);
}
#endif
-#ifdef PCIAGP
- return agp_mmap(v, off, prot);
-#else
return -1;
-#endif
}
int
@@ -269,18 +262,6 @@ vga_pci_ioctl(void *v, u_long cmd, caddr_t addr, int flag, struct proc *pb)
break;
#endif
-#ifdef PCIAGP
- case AGPIOC_INFO:
- case AGPIOC_ACQUIRE:
- case AGPIOC_RELEASE:
- case AGPIOC_SETUP:
- case AGPIOC_ALLOCATE:
- case AGPIOC_DEALLOCATE:
- case AGPIOC_BIND:
- case AGPIOC_UNBIND:
- error = agp_ioctl(v, cmd, addr, flag, pb);
- break;
-#endif
default:
error = ENOTTY;
}
@@ -292,8 +273,5 @@ vga_pci_ioctl(void *v, u_long cmd, caddr_t addr, int flag, struct proc *pb)
void
vga_pci_close(void *v)
{
-#ifdef PCIAGP
- agp_close(v);
-#endif
}
#endif
diff --git a/sys/dev/pci/vga_pcivar.h b/sys/dev/pci/vga_pcivar.h
index 493bbb227b0..44aad8df68a 100644
--- a/sys/dev/pci/vga_pcivar.h
+++ b/sys/dev/pci/vga_pcivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vga_pcivar.h,v 1.8 2007/11/03 10:09:03 martin Exp $ */
+/* $OpenBSD: vga_pcivar.h,v 1.9 2007/11/25 17:11:12 oga Exp $ */
/* $NetBSD: vga_pcivar.h,v 1.1 1998/03/22 15:16:19 drochner Exp $ */
/*
@@ -37,29 +37,6 @@
(PCI_CLASS(class) == PCI_CLASS_PREHISTORIC && \
PCI_SUBCLASS(class) == PCI_SUBCLASS_PREHISTORIC_VGA)) ? 1 : 0)
-enum agp_acquire_state {
- AGP_ACQUIRE_FREE,
- AGP_ACQUIRE_USER,
- AGP_ACQUIRE_KERNEL
-};
-
-/*
- * Data structure to describe an AGP memory allocation.
- */
-TAILQ_HEAD(agp_memory_list, agp_memory);
-struct agp_memory {
- TAILQ_ENTRY(agp_memory) am_link; /* wiring for the tailq */
- int am_id; /* unique id for block */
- vsize_t am_size; /* number of bytes allocated */
- int am_type; /* chipset specific type */
- off_t am_offset; /* page offset if bound */
- int am_is_bound; /* non-zero if bound */
- bus_addr_t am_physical;
- caddr_t am_virtual;
- bus_dmamap_t am_dmamap;
- int am_nseg;
- bus_dma_segment_t *am_dmaseg;
-};
struct vga_pci_softc {
struct device sc_dev;
@@ -81,48 +58,8 @@ struct vga_pci_softc {
u_char sc_cmap_blue[256];
#endif
-#ifdef PCIAGP
- /* agp stuff */
- bus_space_tag_t sc_bt, sc_memt;
- bus_space_handle_t sc_bh;
- bus_addr_t sc_apaddr;
- bus_size_t sc_apsize;
- bus_dma_tag_t sc_dmat;
- struct lock sc_lock; /* lock for access to GATT */
- pcitag_t sc_pcitag; /* PCI tag, in case we need it. */
- pcireg_t sc_id;
- pci_chipset_tag_t sc_pc;
-
- struct agp_methods *sc_methods;
- void *sc_chipc; /* chipset-dependent state */
-
- int sc_opened;
- int sc_capoff;
- int sc_apflags;
- int sc_nextid; /* next memory block id */
-
- u_int32_t sc_maxmem; /* allocation upper bound */
- u_int32_t sc_allocated; /* amount allocated */
- enum agp_acquire_state sc_state;
- struct agp_memory_list sc_memory; /* list of allocated memory */
-#endif
};
-#ifdef PCIAGP
-struct agp_product {
- int ap_vendor;
- int ap_product;
- int (*ap_attach)(struct vga_pci_softc *,
- struct pci_attach_args *, struct pci_attach_args *);
-};
-/* MD-defined */
-extern const struct agp_product agp_products[];
-
-void agp_attach(struct device *, struct device *, void *);
-paddr_t agp_mmap(void *, off_t, int);
-int agp_ioctl(void *, u_long, caddr_t, int, struct proc *);
-#endif /* PCIAGP */
-
int vga_pci_cnattach(bus_space_tag_t, bus_space_tag_t,
pci_chipset_tag_t, int, int, int);