diff options
author | Dave Airlie <airlied@starflyer.(none)> | 2005-07-10 01:38:56 -0400 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2005-07-10 01:38:56 -0400 |
commit | 9c8da5ebbf6f87293cf8555182da271449889a69 (patch) | |
tree | c036835be2ec09249f960518ff2703316257d815 | |
parent | d59431bf96d1e8a3d6d240343f559f5e2ace7f1d (diff) |
drm: update support for drm pci buffers
The DRM needs to change the drm_pci interface for FreeBSD compatiblity,
this patch introduces the drm_dma_handle_t and uses it in the Linux code.
From: Tonnerre Lombard, Eric Anholt, and Sergey Vlasov
Signed-off-by: David Airlie <airlied@linux.ie>
-rw-r--r-- | drivers/char/drm/drmP.h | 16 | ||||
-rw-r--r-- | drivers/char/drm/drm_bufs.c | 22 | ||||
-rw-r--r-- | drivers/char/drm/drm_drv.c | 8 | ||||
-rw-r--r-- | drivers/char/drm/drm_pci.c | 45 | ||||
-rw-r--r-- | drivers/char/drm/drm_vm.c | 8 | ||||
-rw-r--r-- | drivers/char/drm/i915_dma.c | 15 | ||||
-rw-r--r-- | drivers/char/drm/i915_drv.h | 3 |
7 files changed, 78 insertions, 39 deletions
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 804e622436a9..7e633a9ce933 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -527,6 +527,12 @@ typedef struct drm_sigdata { | |||
527 | drm_hw_lock_t *lock; | 527 | drm_hw_lock_t *lock; |
528 | } drm_sigdata_t; | 528 | } drm_sigdata_t; |
529 | 529 | ||
530 | typedef struct drm_dma_handle { | ||
531 | dma_addr_t busaddr; | ||
532 | void *vaddr; | ||
533 | size_t size; | ||
534 | } drm_dma_handle_t; | ||
535 | |||
530 | /** | 536 | /** |
531 | * Mappings list | 537 | * Mappings list |
532 | */ | 538 | */ |
@@ -978,12 +984,10 @@ extern int drm_ati_pcigart_cleanup(drm_device_t *dev, | |||
978 | unsigned long addr, | 984 | unsigned long addr, |
979 | dma_addr_t bus_addr); | 985 | dma_addr_t bus_addr); |
980 | 986 | ||
981 | extern void *drm_pci_alloc(drm_device_t * dev, size_t size, | 987 | extern drm_dma_handle_t *drm_pci_alloc(drm_device_t *dev, size_t size, |
982 | size_t align, dma_addr_t maxaddr, | 988 | size_t align, dma_addr_t maxaddr); |
983 | dma_addr_t * busaddr); | 989 | extern void __drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah); |
984 | 990 | extern void drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah); | |
985 | extern void drm_pci_free(drm_device_t * dev, size_t size, | ||
986 | void *vaddr, dma_addr_t busaddr); | ||
987 | 991 | ||
988 | /* sysfs support (drm_sysfs.c) */ | 992 | /* sysfs support (drm_sysfs.c) */ |
989 | struct drm_sysfs_class; | 993 | struct drm_sysfs_class; |
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index eb3cf550626d..be54efbefe84 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c | |||
@@ -90,6 +90,7 @@ int drm_addmap( struct inode *inode, struct file *filp, | |||
90 | drm_map_t *map; | 90 | drm_map_t *map; |
91 | drm_map_t __user *argp = (void __user *)arg; | 91 | drm_map_t __user *argp = (void __user *)arg; |
92 | drm_map_list_t *list; | 92 | drm_map_list_t *list; |
93 | drm_dma_handle_t *dmah; | ||
93 | 94 | ||
94 | if ( !(filp->f_mode & 3) ) return -EACCES; /* Require read/write */ | 95 | if ( !(filp->f_mode & 3) ) return -EACCES; /* Require read/write */ |
95 | 96 | ||
@@ -181,21 +182,19 @@ int drm_addmap( struct inode *inode, struct file *filp, | |||
181 | map->offset += dev->sg->handle; | 182 | map->offset += dev->sg->handle; |
182 | break; | 183 | break; |
183 | case _DRM_CONSISTENT: | 184 | case _DRM_CONSISTENT: |
184 | { | ||
185 | /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G, | 185 | /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G, |
186 | * As we're limit the address to 2^32-1 (or lses), | 186 | * As we're limiting the address to 2^32-1 (or less), |
187 | * casting it down to 32 bits is no problem, but we | 187 | * casting it down to 32 bits is no problem, but we |
188 | * need to point to a 64bit variable first. */ | 188 | * need to point to a 64bit variable first. */ |
189 | dma_addr_t bus_addr; | 189 | dmah = drm_pci_alloc(dev, map->size, map->size, 0xffffffffUL); |
190 | map->handle = drm_pci_alloc(dev, map->size, map->size, | 190 | if (!dmah) { |
191 | 0xffffffffUL, &bus_addr); | ||
192 | map->offset = (unsigned long)bus_addr; | ||
193 | if (!map->handle) { | ||
194 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 191 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); |
195 | return -ENOMEM; | 192 | return -ENOMEM; |
196 | } | 193 | } |
194 | map->handle = dmah->vaddr; | ||
195 | map->offset = (unsigned long)dmah->busaddr; | ||
196 | kfree(dmah); | ||
197 | break; | 197 | break; |
198 | } | ||
199 | default: | 198 | default: |
200 | drm_free( map, sizeof(*map), DRM_MEM_MAPS ); | 199 | drm_free( map, sizeof(*map), DRM_MEM_MAPS ); |
201 | return -EINVAL; | 200 | return -EINVAL; |
@@ -286,6 +285,8 @@ int drm_rmmap(struct inode *inode, struct file *filp, | |||
286 | } | 285 | } |
287 | 286 | ||
288 | if(!found_maps) { | 287 | if(!found_maps) { |
288 | drm_dma_handle_t dmah; | ||
289 | |||
289 | switch (map->type) { | 290 | switch (map->type) { |
290 | case _DRM_REGISTERS: | 291 | case _DRM_REGISTERS: |
291 | case _DRM_FRAME_BUFFER: | 292 | case _DRM_FRAME_BUFFER: |
@@ -307,7 +308,10 @@ int drm_rmmap(struct inode *inode, struct file *filp, | |||
307 | case _DRM_SCATTER_GATHER: | 308 | case _DRM_SCATTER_GATHER: |
308 | break; | 309 | break; |
309 | case _DRM_CONSISTENT: | 310 | case _DRM_CONSISTENT: |
310 | drm_pci_free(dev, map->size, map->handle, map->offset); | 311 | dmah.vaddr = map->handle; |
312 | dmah.busaddr = map->offset; | ||
313 | dmah.size = map->size; | ||
314 | __drm_pci_free(dev, &dmah); | ||
311 | break; | 315 | break; |
312 | } | 316 | } |
313 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 317 | 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 f4046c8c70b5..ab172ea8e98a 100644 --- a/drivers/char/drm/drm_drv.c +++ b/drivers/char/drm/drm_drv.c | |||
@@ -198,6 +198,8 @@ int drm_takedown( drm_device_t *dev ) | |||
198 | r_list = (drm_map_list_t *)list; | 198 | r_list = (drm_map_list_t *)list; |
199 | 199 | ||
200 | if ( ( map = r_list->map ) ) { | 200 | if ( ( map = r_list->map ) ) { |
201 | drm_dma_handle_t dmah; | ||
202 | |||
201 | switch ( map->type ) { | 203 | switch ( map->type ) { |
202 | case _DRM_REGISTERS: | 204 | case _DRM_REGISTERS: |
203 | case _DRM_FRAME_BUFFER: | 205 | case _DRM_FRAME_BUFFER: |
@@ -229,8 +231,10 @@ int drm_takedown( drm_device_t *dev ) | |||
229 | } | 231 | } |
230 | break; | 232 | break; |
231 | case _DRM_CONSISTENT: | 233 | case _DRM_CONSISTENT: |
232 | drm_pci_free(dev, map->size, | 234 | dmah.vaddr = map->handle; |
233 | map->handle, map->offset); | 235 | dmah.busaddr = map->offset; |
236 | dmah.size = map->size; | ||
237 | __drm_pci_free(dev, &dmah); | ||
234 | break; | 238 | break; |
235 | } | 239 | } |
236 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 240 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); |
diff --git a/drivers/char/drm/drm_pci.c b/drivers/char/drm/drm_pci.c index 192e8762571c..3e452e8967fa 100644 --- a/drivers/char/drm/drm_pci.c +++ b/drivers/char/drm/drm_pci.c | |||
@@ -46,10 +46,10 @@ | |||
46 | /** | 46 | /** |
47 | * \brief Allocate a PCI consistent memory block, for DMA. | 47 | * \brief Allocate a PCI consistent memory block, for DMA. |
48 | */ | 48 | */ |
49 | void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align, | 49 | drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align, |
50 | dma_addr_t maxaddr, dma_addr_t * busaddr) | 50 | dma_addr_t maxaddr) |
51 | { | 51 | { |
52 | void *address; | 52 | drm_dma_handle_t *dmah; |
53 | #if DRM_DEBUG_MEMORY | 53 | #if DRM_DEBUG_MEMORY |
54 | int area = DRM_MEM_DMA; | 54 | int area = DRM_MEM_DMA; |
55 | 55 | ||
@@ -74,13 +74,19 @@ void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align, | |||
74 | return NULL; | 74 | return NULL; |
75 | } | 75 | } |
76 | 76 | ||
77 | address = pci_alloc_consistent(dev->pdev, size, busaddr); | 77 | dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL); |
78 | if (!dmah) | ||
79 | return NULL; | ||
80 | |||
81 | dmah->size = size; | ||
82 | dmah->vaddr = pci_alloc_consistent(dev->pdev, size, &dmah->busaddr); | ||
78 | 83 | ||
79 | #if DRM_DEBUG_MEMORY | 84 | #if DRM_DEBUG_MEMORY |
80 | if (address == NULL) { | 85 | if (dmah->vaddr == NULL) { |
81 | spin_lock(&drm_mem_lock); | 86 | spin_lock(&drm_mem_lock); |
82 | ++drm_mem_stats[area].fail_count; | 87 | ++drm_mem_stats[area].fail_count; |
83 | spin_unlock(&drm_mem_lock); | 88 | spin_unlock(&drm_mem_lock); |
89 | kfree(dmah); | ||
84 | return NULL; | 90 | return NULL; |
85 | } | 91 | } |
86 | 92 | ||
@@ -90,21 +96,25 @@ void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align, | |||
90 | drm_ram_used += size; | 96 | drm_ram_used += size; |
91 | spin_unlock(&drm_mem_lock); | 97 | spin_unlock(&drm_mem_lock); |
92 | #else | 98 | #else |
93 | if (address == NULL) | 99 | if (dmah->vaddr == NULL) { |
100 | kfree(dmah); | ||
94 | return NULL; | 101 | return NULL; |
102 | } | ||
95 | #endif | 103 | #endif |
96 | 104 | ||
97 | memset(address, 0, size); | 105 | memset(dmah->vaddr, 0, size); |
98 | 106 | ||
99 | return address; | 107 | return dmah; |
100 | } | 108 | } |
101 | EXPORT_SYMBOL(drm_pci_alloc); | 109 | EXPORT_SYMBOL(drm_pci_alloc); |
102 | 110 | ||
103 | /** | 111 | /** |
104 | * \brief Free a PCI consistent memory block. | 112 | * \brief Free a PCI consistent memory block with freeing its descriptor. |
113 | * | ||
114 | * This function is for internal use in the Linux-specific DRM core code. | ||
105 | */ | 115 | */ |
106 | void | 116 | void |
107 | drm_pci_free(drm_device_t * dev, size_t size, void *vaddr, dma_addr_t busaddr) | 117 | __drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah) |
108 | { | 118 | { |
109 | #if DRM_DEBUG_MEMORY | 119 | #if DRM_DEBUG_MEMORY |
110 | int area = DRM_MEM_DMA; | 120 | int area = DRM_MEM_DMA; |
@@ -112,12 +122,13 @@ drm_pci_free(drm_device_t * dev, size_t size, void *vaddr, dma_addr_t busaddr) | |||
112 | int free_count; | 122 | int free_count; |
113 | #endif | 123 | #endif |
114 | 124 | ||
115 | if (!vaddr) { | 125 | if (!dmah->vaddr) { |
116 | #if DRM_DEBUG_MEMORY | 126 | #if DRM_DEBUG_MEMORY |
117 | DRM_MEM_ERROR(area, "Attempt to free address 0\n"); | 127 | DRM_MEM_ERROR(area, "Attempt to free address 0\n"); |
118 | #endif | 128 | #endif |
119 | } else { | 129 | } else { |
120 | pci_free_consistent(dev->pdev, size, vaddr, busaddr); | 130 | pci_free_consistent(dev->pdev, dmah->size, dmah->vaddr, |
131 | dmah->busaddr); | ||
121 | } | 132 | } |
122 | 133 | ||
123 | #if DRM_DEBUG_MEMORY | 134 | #if DRM_DEBUG_MEMORY |
@@ -135,6 +146,16 @@ drm_pci_free(drm_device_t * dev, size_t size, void *vaddr, dma_addr_t busaddr) | |||
135 | #endif | 146 | #endif |
136 | 147 | ||
137 | } | 148 | } |
149 | |||
150 | /** | ||
151 | * \brief Free a PCI consistent memory block | ||
152 | */ | ||
153 | void | ||
154 | drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah) | ||
155 | { | ||
156 | __drm_pci_free(dev, dmah); | ||
157 | kfree(dmah); | ||
158 | } | ||
138 | EXPORT_SYMBOL(drm_pci_free); | 159 | EXPORT_SYMBOL(drm_pci_free); |
139 | 160 | ||
140 | /*@}*/ | 161 | /*@}*/ |
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c index 644ec9dadc05..675d2397def9 100644 --- a/drivers/char/drm/drm_vm.c +++ b/drivers/char/drm/drm_vm.c | |||
@@ -210,6 +210,8 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) | |||
210 | } | 210 | } |
211 | 211 | ||
212 | if(!found_maps) { | 212 | if(!found_maps) { |
213 | drm_dma_handle_t dmah; | ||
214 | |||
213 | switch (map->type) { | 215 | switch (map->type) { |
214 | case _DRM_REGISTERS: | 216 | case _DRM_REGISTERS: |
215 | case _DRM_FRAME_BUFFER: | 217 | case _DRM_FRAME_BUFFER: |
@@ -229,8 +231,10 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) | |||
229 | case _DRM_SCATTER_GATHER: | 231 | case _DRM_SCATTER_GATHER: |
230 | break; | 232 | break; |
231 | case _DRM_CONSISTENT: | 233 | case _DRM_CONSISTENT: |
232 | drm_pci_free(dev, map->size, map->handle, | 234 | dmah.vaddr = map->handle; |
233 | map->offset); | 235 | dmah.busaddr = map->offset; |
236 | dmah.size = map->size; | ||
237 | __drm_pci_free(dev, &dmah); | ||
234 | break; | 238 | break; |
235 | } | 239 | } |
236 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 240 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); |
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c index acf9e52a9507..759f22943eb1 100644 --- a/drivers/char/drm/i915_dma.c +++ b/drivers/char/drm/i915_dma.c | |||
@@ -95,9 +95,8 @@ static int i915_dma_cleanup(drm_device_t * dev) | |||
95 | drm_core_ioremapfree( &dev_priv->ring.map, dev); | 95 | drm_core_ioremapfree( &dev_priv->ring.map, dev); |
96 | } | 96 | } |
97 | 97 | ||
98 | if (dev_priv->hw_status_page) { | 98 | if (dev_priv->status_page_dmah) { |
99 | drm_pci_free(dev, PAGE_SIZE, dev_priv->hw_status_page, | 99 | drm_pci_free(dev, dev_priv->status_page_dmah); |
100 | dev_priv->dma_status_page); | ||
101 | /* Need to rewrite hardware status page */ | 100 | /* Need to rewrite hardware status page */ |
102 | I915_WRITE(0x02080, 0x1ffff000); | 101 | I915_WRITE(0x02080, 0x1ffff000); |
103 | } | 102 | } |
@@ -174,16 +173,18 @@ static int i915_initialize(drm_device_t * dev, | |||
174 | dev_priv->allow_batchbuffer = 1; | 173 | dev_priv->allow_batchbuffer = 1; |
175 | 174 | ||
176 | /* Program Hardware Status Page */ | 175 | /* Program Hardware Status Page */ |
177 | dev_priv->hw_status_page = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, | 176 | dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, |
178 | 0xffffffff, | 177 | 0xffffffff); |
179 | &dev_priv->dma_status_page); | ||
180 | 178 | ||
181 | if (!dev_priv->hw_status_page) { | 179 | if (!dev_priv->status_page_dmah) { |
182 | dev->dev_private = (void *)dev_priv; | 180 | dev->dev_private = (void *)dev_priv; |
183 | i915_dma_cleanup(dev); | 181 | i915_dma_cleanup(dev); |
184 | DRM_ERROR("Can not allocate hardware status page\n"); | 182 | DRM_ERROR("Can not allocate hardware status page\n"); |
185 | return DRM_ERR(ENOMEM); | 183 | return DRM_ERR(ENOMEM); |
186 | } | 184 | } |
185 | dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; | ||
186 | dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; | ||
187 | |||
187 | memset(dev_priv->hw_status_page, 0, PAGE_SIZE); | 188 | memset(dev_priv->hw_status_page, 0, PAGE_SIZE); |
188 | DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); | 189 | DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); |
189 | 190 | ||
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index 9c37d2367dd5..93080868d18f 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h | |||
@@ -79,9 +79,10 @@ typedef struct drm_i915_private { | |||
79 | drm_i915_sarea_t *sarea_priv; | 79 | drm_i915_sarea_t *sarea_priv; |
80 | drm_i915_ring_buffer_t ring; | 80 | drm_i915_ring_buffer_t ring; |
81 | 81 | ||
82 | drm_dma_handle_t *status_page_dmah; | ||
82 | void *hw_status_page; | 83 | void *hw_status_page; |
83 | unsigned long counter; | ||
84 | dma_addr_t dma_status_page; | 84 | dma_addr_t dma_status_page; |
85 | unsigned long counter; | ||
85 | 86 | ||
86 | int back_offset; | 87 | int back_offset; |
87 | int front_offset; | 88 | int front_offset; |