summaryrefslogtreecommitdiffstats
path: root/drivers/char/drm
diff options
context:
space:
mode:
authorDave Airlie <airlied@starflyer.(none)>2005-07-10 14:34:13 +1000
committerDave Airlie <airlied@linux.ie>2005-07-10 14:34:13 +1000
commit2d0f9eaff8e1d08b9707f5d24fe6b0ac95d231e3 (patch)
tree6602c6a936254ae1175073fdd3f800ed67730c17 /drivers/char/drm
parentf179bc77d09b9087bfc559d0368bba350342ac76 (diff)
downloadlinux-2d0f9eaff8e1d08b9707f5d24fe6b0ac95d231e3.tar.gz
linux-2d0f9eaff8e1d08b9707f5d24fe6b0ac95d231e3.tar.bz2
linux-2d0f9eaff8e1d08b9707f5d24fe6b0ac95d231e3.zip
drm: add _DRM_CONSISTENT map type
Added a new DRM map type _DRM_CONSISTENT for consistent PCI memory. It uses drm_pci_alloc/free for allocating/freeing the memory. From: Felix Kuhling <fxkuehl@gmx.de> Signed-off-by: David Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/char/drm')
-rw-r--r--drivers/char/drm/drm.h3
-rw-r--r--drivers/char/drm/drm_bufs.c20
-rw-r--r--drivers/char/drm/drm_drv.c4
-rw-r--r--drivers/char/drm/drm_proc.c13
-rw-r--r--drivers/char/drm/drm_vm.c7
5 files changed, 40 insertions, 7 deletions
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h
index e8371dd87fbc..50c4d981c497 100644
--- a/drivers/char/drm/drm.h
+++ b/drivers/char/drm/drm.h
@@ -209,7 +209,8 @@ typedef enum drm_map_type {
_DRM_REGISTERS = 1, /**< no caching, no core dump */
_DRM_SHM = 2, /**< shared, cached */
_DRM_AGP = 3, /**< AGP/GART */
- _DRM_SCATTER_GATHER = 4 /**< Scatter/gather memory for PCI DMA */
+ _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */
+ _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */
} drm_map_type_t;
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index 4c6191d231b8..89f301ffd97e 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -180,7 +180,22 @@ int drm_addmap( struct inode *inode, struct file *filp,
}
map->offset += dev->sg->handle;
break;
-
+ case _DRM_CONSISTENT:
+ {
+ /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G,
+ * As we're limit the address to 2^32-1 (or lses),
+ * casting it down to 32 bits is no problem, but we
+ * need to point to a 64bit variable first. */
+ dma_addr_t bus_addr;
+ map->handle = drm_pci_alloc(dev, map->size, map->size,
+ 0xffffffffUL, &bus_addr);
+ map->offset = (unsigned long)bus_addr;
+ if (!map->handle) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ return -ENOMEM;
+ }
+ break;
+ }
default:
drm_free( map, sizeof(*map), DRM_MEM_MAPS );
return -EINVAL;
@@ -291,6 +306,9 @@ int drm_rmmap(struct inode *inode, struct file *filp,
case _DRM_AGP:
case _DRM_SCATTER_GATHER:
break;
+ case _DRM_CONSISTENT:
+ drm_pci_free(dev, map->size, map->handle, map->offset);
+ break;
}
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
}
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index 3333c250c4d9..f4046c8c70b5 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -228,6 +228,10 @@ int drm_takedown( drm_device_t *dev )
dev->sg = NULL;
}
break;
+ case _DRM_CONSISTENT:
+ drm_pci_free(dev, map->size,
+ map->handle, map->offset);
+ break;
}
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
}
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
index 4774087d2e9e..f4154cc71abb 100644
--- a/drivers/char/drm/drm_proc.c
+++ b/drivers/char/drm/drm_proc.c
@@ -210,8 +210,8 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
/* Hardcoded from _DRM_FRAME_BUFFER,
_DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
- _DRM_SCATTER_GATHER. */
- const char *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
+ _DRM_SCATTER_GATHER and _DRM_CONSISTENT */
+ const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
const char *type;
int i;
@@ -229,9 +229,12 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
if (dev->maplist != NULL) list_for_each(list, &dev->maplist->head) {
r_list = list_entry(list, drm_map_list_t, head);
map = r_list->map;
- if(!map) continue;
- if (map->type < 0 || map->type > 4) type = "??";
- else type = types[map->type];
+ if(!map)
+ continue;
+ if (map->type < 0 || map->type > 5)
+ type = "??";
+ else
+ type = types[map->type];
DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
i,
map->offset,
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
index 621220f3f372..644ec9dadc05 100644
--- a/drivers/char/drm/drm_vm.c
+++ b/drivers/char/drm/drm_vm.c
@@ -228,6 +228,10 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
case _DRM_AGP:
case _DRM_SCATTER_GATHER:
break;
+ case _DRM_CONSISTENT:
+ drm_pci_free(dev, map->size, map->handle,
+ map->offset);
+ break;
}
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
}
@@ -645,6 +649,9 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_ops = &drm_vm_ops;
break;
case _DRM_SHM:
+ case _DRM_CONSISTENT:
+ /* Consistent memory is really like shared memory. It's only
+ * allocate in a different way */
vma->vm_ops = &drm_vm_shm_ops;
vma->vm_private_data = (void *)map;
/* Don't let this area swap. Change when