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>
This commit is contained in:
parent
d59431bf96
commit
9c8da5ebbf
7 changed files with 78 additions and 39 deletions
|
@ -527,6 +527,12 @@ typedef struct drm_sigdata {
|
||||||
drm_hw_lock_t *lock;
|
drm_hw_lock_t *lock;
|
||||||
} drm_sigdata_t;
|
} drm_sigdata_t;
|
||||||
|
|
||||||
|
typedef struct drm_dma_handle {
|
||||||
|
dma_addr_t busaddr;
|
||||||
|
void *vaddr;
|
||||||
|
size_t size;
|
||||||
|
} drm_dma_handle_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mappings list
|
* Mappings list
|
||||||
*/
|
*/
|
||||||
|
@ -978,12 +984,10 @@ extern int drm_ati_pcigart_cleanup(drm_device_t *dev,
|
||||||
unsigned long addr,
|
unsigned long addr,
|
||||||
dma_addr_t bus_addr);
|
dma_addr_t bus_addr);
|
||||||
|
|
||||||
extern void *drm_pci_alloc(drm_device_t * dev, size_t size,
|
extern drm_dma_handle_t *drm_pci_alloc(drm_device_t *dev, size_t size,
|
||||||
size_t align, dma_addr_t maxaddr,
|
size_t align, dma_addr_t maxaddr);
|
||||||
dma_addr_t * busaddr);
|
extern void __drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah);
|
||||||
|
extern void drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah);
|
||||||
extern void drm_pci_free(drm_device_t * dev, size_t size,
|
|
||||||
void *vaddr, dma_addr_t busaddr);
|
|
||||||
|
|
||||||
/* sysfs support (drm_sysfs.c) */
|
/* sysfs support (drm_sysfs.c) */
|
||||||
struct drm_sysfs_class;
|
struct drm_sysfs_class;
|
||||||
|
|
|
@ -90,6 +90,7 @@ int drm_addmap( struct inode *inode, struct file *filp,
|
||||||
drm_map_t *map;
|
drm_map_t *map;
|
||||||
drm_map_t __user *argp = (void __user *)arg;
|
drm_map_t __user *argp = (void __user *)arg;
|
||||||
drm_map_list_t *list;
|
drm_map_list_t *list;
|
||||||
|
drm_dma_handle_t *dmah;
|
||||||
|
|
||||||
if ( !(filp->f_mode & 3) ) return -EACCES; /* Require read/write */
|
if ( !(filp->f_mode & 3) ) return -EACCES; /* Require read/write */
|
||||||
|
|
||||||
|
@ -181,21 +182,19 @@ int drm_addmap( struct inode *inode, struct file *filp,
|
||||||
map->offset += dev->sg->handle;
|
map->offset += dev->sg->handle;
|
||||||
break;
|
break;
|
||||||
case _DRM_CONSISTENT:
|
case _DRM_CONSISTENT:
|
||||||
{
|
|
||||||
/* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G,
|
/* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G,
|
||||||
* As we're limit the address to 2^32-1 (or lses),
|
* As we're limiting the address to 2^32-1 (or less),
|
||||||
* casting it down to 32 bits is no problem, but we
|
* casting it down to 32 bits is no problem, but we
|
||||||
* need to point to a 64bit variable first. */
|
* need to point to a 64bit variable first. */
|
||||||
dma_addr_t bus_addr;
|
dmah = drm_pci_alloc(dev, map->size, map->size, 0xffffffffUL);
|
||||||
map->handle = drm_pci_alloc(dev, map->size, map->size,
|
if (!dmah) {
|
||||||
0xffffffffUL, &bus_addr);
|
|
||||||
map->offset = (unsigned long)bus_addr;
|
|
||||||
if (!map->handle) {
|
|
||||||
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
map->handle = dmah->vaddr;
|
||||||
|
map->offset = (unsigned long)dmah->busaddr;
|
||||||
|
kfree(dmah);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
drm_free( map, sizeof(*map), DRM_MEM_MAPS );
|
drm_free( map, sizeof(*map), DRM_MEM_MAPS );
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -286,6 +285,8 @@ int drm_rmmap(struct inode *inode, struct file *filp,
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!found_maps) {
|
if(!found_maps) {
|
||||||
|
drm_dma_handle_t dmah;
|
||||||
|
|
||||||
switch (map->type) {
|
switch (map->type) {
|
||||||
case _DRM_REGISTERS:
|
case _DRM_REGISTERS:
|
||||||
case _DRM_FRAME_BUFFER:
|
case _DRM_FRAME_BUFFER:
|
||||||
|
@ -307,7 +308,10 @@ int drm_rmmap(struct inode *inode, struct file *filp,
|
||||||
case _DRM_SCATTER_GATHER:
|
case _DRM_SCATTER_GATHER:
|
||||||
break;
|
break;
|
||||||
case _DRM_CONSISTENT:
|
case _DRM_CONSISTENT:
|
||||||
drm_pci_free(dev, map->size, map->handle, map->offset);
|
dmah.vaddr = map->handle;
|
||||||
|
dmah.busaddr = map->offset;
|
||||||
|
dmah.size = map->size;
|
||||||
|
__drm_pci_free(dev, &dmah);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
||||||
|
|
|
@ -198,6 +198,8 @@ int drm_takedown( drm_device_t *dev )
|
||||||
r_list = (drm_map_list_t *)list;
|
r_list = (drm_map_list_t *)list;
|
||||||
|
|
||||||
if ( ( map = r_list->map ) ) {
|
if ( ( map = r_list->map ) ) {
|
||||||
|
drm_dma_handle_t dmah;
|
||||||
|
|
||||||
switch ( map->type ) {
|
switch ( map->type ) {
|
||||||
case _DRM_REGISTERS:
|
case _DRM_REGISTERS:
|
||||||
case _DRM_FRAME_BUFFER:
|
case _DRM_FRAME_BUFFER:
|
||||||
|
@ -229,8 +231,10 @@ int drm_takedown( drm_device_t *dev )
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case _DRM_CONSISTENT:
|
case _DRM_CONSISTENT:
|
||||||
drm_pci_free(dev, map->size,
|
dmah.vaddr = map->handle;
|
||||||
map->handle, map->offset);
|
dmah.busaddr = map->offset;
|
||||||
|
dmah.size = map->size;
|
||||||
|
__drm_pci_free(dev, &dmah);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
||||||
|
|
|
@ -46,10 +46,10 @@
|
||||||
/**
|
/**
|
||||||
* \brief Allocate a PCI consistent memory block, for DMA.
|
* \brief Allocate a PCI consistent memory block, for DMA.
|
||||||
*/
|
*/
|
||||||
void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
|
drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
|
||||||
dma_addr_t maxaddr, dma_addr_t * busaddr)
|
dma_addr_t maxaddr)
|
||||||
{
|
{
|
||||||
void *address;
|
drm_dma_handle_t *dmah;
|
||||||
#if DRM_DEBUG_MEMORY
|
#if DRM_DEBUG_MEMORY
|
||||||
int area = DRM_MEM_DMA;
|
int area = DRM_MEM_DMA;
|
||||||
|
|
||||||
|
@ -74,13 +74,19 @@ void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
address = pci_alloc_consistent(dev->pdev, size, busaddr);
|
dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL);
|
||||||
|
if (!dmah)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dmah->size = size;
|
||||||
|
dmah->vaddr = pci_alloc_consistent(dev->pdev, size, &dmah->busaddr);
|
||||||
|
|
||||||
#if DRM_DEBUG_MEMORY
|
#if DRM_DEBUG_MEMORY
|
||||||
if (address == NULL) {
|
if (dmah->vaddr == NULL) {
|
||||||
spin_lock(&drm_mem_lock);
|
spin_lock(&drm_mem_lock);
|
||||||
++drm_mem_stats[area].fail_count;
|
++drm_mem_stats[area].fail_count;
|
||||||
spin_unlock(&drm_mem_lock);
|
spin_unlock(&drm_mem_lock);
|
||||||
|
kfree(dmah);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,21 +96,25 @@ void *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
|
||||||
drm_ram_used += size;
|
drm_ram_used += size;
|
||||||
spin_unlock(&drm_mem_lock);
|
spin_unlock(&drm_mem_lock);
|
||||||
#else
|
#else
|
||||||
if (address == NULL)
|
if (dmah->vaddr == NULL) {
|
||||||
|
kfree(dmah);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
memset(address, 0, size);
|
memset(dmah->vaddr, 0, size);
|
||||||
|
|
||||||
return address;
|
return dmah;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_pci_alloc);
|
EXPORT_SYMBOL(drm_pci_alloc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Free a PCI consistent memory block.
|
* \brief Free a PCI consistent memory block with freeing its descriptor.
|
||||||
|
*
|
||||||
|
* This function is for internal use in the Linux-specific DRM core code.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
drm_pci_free(drm_device_t * dev, size_t size, void *vaddr, dma_addr_t busaddr)
|
__drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah)
|
||||||
{
|
{
|
||||||
#if DRM_DEBUG_MEMORY
|
#if DRM_DEBUG_MEMORY
|
||||||
int area = DRM_MEM_DMA;
|
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)
|
||||||
int free_count;
|
int free_count;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!vaddr) {
|
if (!dmah->vaddr) {
|
||||||
#if DRM_DEBUG_MEMORY
|
#if DRM_DEBUG_MEMORY
|
||||||
DRM_MEM_ERROR(area, "Attempt to free address 0\n");
|
DRM_MEM_ERROR(area, "Attempt to free address 0\n");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
pci_free_consistent(dev->pdev, size, vaddr, busaddr);
|
pci_free_consistent(dev->pdev, dmah->size, dmah->vaddr,
|
||||||
|
dmah->busaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DRM_DEBUG_MEMORY
|
#if DRM_DEBUG_MEMORY
|
||||||
|
@ -135,6 +146,16 @@ drm_pci_free(drm_device_t * dev, size_t size, void *vaddr, dma_addr_t busaddr)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Free a PCI consistent memory block
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah)
|
||||||
|
{
|
||||||
|
__drm_pci_free(dev, dmah);
|
||||||
|
kfree(dmah);
|
||||||
|
}
|
||||||
EXPORT_SYMBOL(drm_pci_free);
|
EXPORT_SYMBOL(drm_pci_free);
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
|
@ -210,6 +210,8 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!found_maps) {
|
if(!found_maps) {
|
||||||
|
drm_dma_handle_t dmah;
|
||||||
|
|
||||||
switch (map->type) {
|
switch (map->type) {
|
||||||
case _DRM_REGISTERS:
|
case _DRM_REGISTERS:
|
||||||
case _DRM_FRAME_BUFFER:
|
case _DRM_FRAME_BUFFER:
|
||||||
|
@ -229,8 +231,10 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
|
||||||
case _DRM_SCATTER_GATHER:
|
case _DRM_SCATTER_GATHER:
|
||||||
break;
|
break;
|
||||||
case _DRM_CONSISTENT:
|
case _DRM_CONSISTENT:
|
||||||
drm_pci_free(dev, map->size, map->handle,
|
dmah.vaddr = map->handle;
|
||||||
map->offset);
|
dmah.busaddr = map->offset;
|
||||||
|
dmah.size = map->size;
|
||||||
|
__drm_pci_free(dev, &dmah);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
||||||
|
|
|
@ -95,9 +95,8 @@ static int i915_dma_cleanup(drm_device_t * dev)
|
||||||
drm_core_ioremapfree( &dev_priv->ring.map, dev);
|
drm_core_ioremapfree( &dev_priv->ring.map, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev_priv->hw_status_page) {
|
if (dev_priv->status_page_dmah) {
|
||||||
drm_pci_free(dev, PAGE_SIZE, dev_priv->hw_status_page,
|
drm_pci_free(dev, dev_priv->status_page_dmah);
|
||||||
dev_priv->dma_status_page);
|
|
||||||
/* Need to rewrite hardware status page */
|
/* Need to rewrite hardware status page */
|
||||||
I915_WRITE(0x02080, 0x1ffff000);
|
I915_WRITE(0x02080, 0x1ffff000);
|
||||||
}
|
}
|
||||||
|
@ -174,16 +173,18 @@ static int i915_initialize(drm_device_t * dev,
|
||||||
dev_priv->allow_batchbuffer = 1;
|
dev_priv->allow_batchbuffer = 1;
|
||||||
|
|
||||||
/* Program Hardware Status Page */
|
/* Program Hardware Status Page */
|
||||||
dev_priv->hw_status_page = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE,
|
dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE,
|
||||||
0xffffffff,
|
0xffffffff);
|
||||||
&dev_priv->dma_status_page);
|
|
||||||
|
|
||||||
if (!dev_priv->hw_status_page) {
|
if (!dev_priv->status_page_dmah) {
|
||||||
dev->dev_private = (void *)dev_priv;
|
dev->dev_private = (void *)dev_priv;
|
||||||
i915_dma_cleanup(dev);
|
i915_dma_cleanup(dev);
|
||||||
DRM_ERROR("Can not allocate hardware status page\n");
|
DRM_ERROR("Can not allocate hardware status page\n");
|
||||||
return DRM_ERR(ENOMEM);
|
return DRM_ERR(ENOMEM);
|
||||||
}
|
}
|
||||||
|
dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
|
||||||
|
dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
|
||||||
|
|
||||||
memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
|
memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
|
||||||
DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
|
DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
|
||||||
|
|
||||||
|
|
|
@ -79,9 +79,10 @@ typedef struct drm_i915_private {
|
||||||
drm_i915_sarea_t *sarea_priv;
|
drm_i915_sarea_t *sarea_priv;
|
||||||
drm_i915_ring_buffer_t ring;
|
drm_i915_ring_buffer_t ring;
|
||||||
|
|
||||||
|
drm_dma_handle_t *status_page_dmah;
|
||||||
void *hw_status_page;
|
void *hw_status_page;
|
||||||
unsigned long counter;
|
|
||||||
dma_addr_t dma_status_page;
|
dma_addr_t dma_status_page;
|
||||||
|
unsigned long counter;
|
||||||
|
|
||||||
int back_offset;
|
int back_offset;
|
||||||
int front_offset;
|
int front_offset;
|
||||||
|
|
Loading…
Add table
Reference in a new issue