summaryrefslogtreecommitdiffstats
path: root/sys/dev/pci/drm/drm_memory.c
diff options
context:
space:
mode:
authoroga <oga@openbsd.org>2008-05-06 19:19:02 +0000
committeroga <oga@openbsd.org>2008-05-06 19:19:02 +0000
commitf57a45105f83a5bad37e93ae747ec3477660a093 (patch)
treebe6e5efe099679950112b5d859693c0ea2e9a2fe /sys/dev/pci/drm/drm_memory.c
parentretire vfs_mountroot(); (diff)
downloadwireguard-openbsd-f57a45105f83a5bad37e93ae747ec3477660a093.tar.xz
wireguard-openbsd-f57a45105f83a5bad37e93ae747ec3477660a093.zip
currently agp_i810 needs to map the same BAR as inteldrm, this obviously
fails. In order to allow this, implement an API so that drm and agp can share mappings for the BARs. Now it works as it should. tested by many. ok kettenis, miod said he'd look at it when it's in tree.
Diffstat (limited to 'sys/dev/pci/drm/drm_memory.c')
-rw-r--r--sys/dev/pci/drm/drm_memory.c52
1 files changed, 45 insertions, 7 deletions
diff --git a/sys/dev/pci/drm/drm_memory.c b/sys/dev/pci/drm/drm_memory.c
index 8d3ae1d4a5f..5900b431d17 100644
--- a/sys/dev/pci/drm/drm_memory.c
+++ b/sys/dev/pci/drm/drm_memory.c
@@ -97,13 +97,48 @@ drm_ioremap(drm_device_t *dev, drm_local_map_t *map)
#ifdef __FreeBSD__
return pmap_mapdev(map->offset, map->size);
#elif defined(__NetBSD__) || defined(__OpenBSD__)
- int ret;
- if (!map->bst)
- map->bst = dev->pa.pa_memt;
- if ((ret = bus_space_map(map->bst, map->offset, map->size,
- BUS_SPACE_MAP_LINEAR, &map->bsh))) {
- return NULL;
+ struct vga_pci_bar *bar = NULL;
+ int i;
+
+ DRM_DEBUG("offset: 0x%x size: 0x%x type: %d\n", map->offset, map->size,
+ map->type);
+
+ if (map->type == _DRM_AGP || map->type == _DRM_FRAME_BUFFER) {
+ /*
+ * there can be multiple agp maps in the same BAR, agp also
+ * quite possibly isn't the same as the vga device, just try
+ * to map it.
+ */
+ DRM_DEBUG("AGP map\n");
+ map->bst = dev->pa.pa_memt;
+ if (bus_space_map(map->bst, map->offset,
+ map->size, BUS_SPACE_MAP_LINEAR, &map->bsh)) {
+ DRM_ERROR("ioremap fail\n");
+ return (NULL);
+ }
+ goto done;
+ } else {
+ for (i = 0 ; i < DRM_MAX_PCI_RESOURCE; ++i) {
+ bar = vga_pci_bar_info(dev->vga_softc, i);
+ if (bar == NULL)
+ continue;
+
+ if (bar->base == map->offset) {
+ DRM_DEBUG("REGISTERS map\n");
+ map->bsr = vga_pci_bar_map(dev->vga_softc,
+ bar->addr, map->size, BUS_SPACE_MAP_LINEAR);
+ if (map->bsr == NULL) {
+ DRM_ERROR("ioremap fail\n");
+ return (NULL);
+ }
+ map->bst = map->bsr->bst;
+ map->bsh = map->bsr->bsh;
+ goto done;
+ }
+ }
}
+done:
+ /* handles are still supposed to be kernel virtual addresses */
return bus_space_vaddr(map->bst, map->bsh);
#endif
}
@@ -114,7 +149,10 @@ drm_ioremapfree(drm_local_map_t *map)
#ifdef __FreeBSD__
pmap_unmapdev((vm_offset_t) map->handle, map->size);
#elif defined(__NetBSD__) || defined(__OpenBSD__)
- bus_space_unmap(map->bst, map->bsh, map->size);
+ if (map != NULL && map->bsr != NULL)
+ vga_pci_bar_unmap(map->bsr);
+ else
+ bus_space_unmap(map->bst, map->bsh, map->size);
#endif
}