Unify infrastructure for allocating (not yet freeing) on-card / GART memory.
parent
5362cc723e
commit
f96bff9e21
|
@ -37,11 +37,12 @@ static void xgi_cmdlist_reset(struct xgi_info * info);
|
||||||
int xgi_cmdlist_initialize(struct xgi_info * info, size_t size)
|
int xgi_cmdlist_initialize(struct xgi_info * info, size_t size)
|
||||||
{
|
{
|
||||||
struct xgi_mem_alloc mem_alloc = {
|
struct xgi_mem_alloc mem_alloc = {
|
||||||
|
.location = XGI_MEMLOC_NON_LOCAL,
|
||||||
.size = size,
|
.size = size,
|
||||||
};
|
};
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = xgi_pcie_alloc(info, &mem_alloc, 0);
|
err = xgi_alloc(info, &mem_alloc, 0);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
|
|
||||||
#define DRIVER_MAJOR 0
|
#define DRIVER_MAJOR 0
|
||||||
#define DRIVER_MINOR 10
|
#define DRIVER_MINOR 10
|
||||||
#define DRIVER_PATCHLEVEL 2
|
#define DRIVER_PATCHLEVEL 3
|
||||||
|
|
||||||
#include "xgi_cmdlist.h"
|
#include "xgi_cmdlist.h"
|
||||||
#include "xgi_drm.h"
|
#include "xgi_drm.h"
|
||||||
|
@ -92,8 +92,6 @@ struct xgi_info {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct kmem_cache *xgi_mem_block_cache;
|
extern struct kmem_cache *xgi_mem_block_cache;
|
||||||
extern struct xgi_mem_block *xgi_mem_alloc(struct xgi_mem_heap * heap,
|
|
||||||
unsigned long size);
|
|
||||||
extern int xgi_mem_free(struct xgi_mem_heap * heap, unsigned long offset,
|
extern int xgi_mem_free(struct xgi_mem_heap * heap, unsigned long offset,
|
||||||
struct drm_file * filp);
|
struct drm_file * filp);
|
||||||
extern int xgi_mem_heap_init(struct xgi_mem_heap * heap, unsigned int start,
|
extern int xgi_mem_heap_init(struct xgi_mem_heap * heap, unsigned int start,
|
||||||
|
@ -102,7 +100,7 @@ extern void xgi_mem_heap_cleanup(struct xgi_mem_heap * heap);
|
||||||
|
|
||||||
extern int xgi_fb_heap_init(struct xgi_info * info);
|
extern int xgi_fb_heap_init(struct xgi_info * info);
|
||||||
|
|
||||||
extern int xgi_fb_alloc(struct xgi_info * info, struct xgi_mem_alloc * alloc,
|
extern int xgi_alloc(struct xgi_info * info, struct xgi_mem_alloc * alloc,
|
||||||
struct drm_file * filp);
|
struct drm_file * filp);
|
||||||
|
|
||||||
extern int xgi_fb_free(struct xgi_info * info, unsigned long offset,
|
extern int xgi_fb_free(struct xgi_info * info, unsigned long offset,
|
||||||
|
@ -111,9 +109,6 @@ extern int xgi_fb_free(struct xgi_info * info, unsigned long offset,
|
||||||
extern int xgi_pcie_heap_init(struct xgi_info * info);
|
extern int xgi_pcie_heap_init(struct xgi_info * info);
|
||||||
extern void xgi_pcie_lut_cleanup(struct xgi_info * info);
|
extern void xgi_pcie_lut_cleanup(struct xgi_info * info);
|
||||||
|
|
||||||
extern int xgi_pcie_alloc(struct xgi_info * info,
|
|
||||||
struct xgi_mem_alloc * alloc, struct drm_file * filp);
|
|
||||||
|
|
||||||
extern int xgi_pcie_free(struct xgi_info * info, unsigned long offset,
|
extern int xgi_pcie_free(struct xgi_info * info, unsigned long offset,
|
||||||
struct drm_file * filp);
|
struct drm_file * filp);
|
||||||
|
|
||||||
|
|
|
@ -99,8 +99,8 @@ struct xgi_mem_block *xgi_mem_new_node(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct xgi_mem_block *xgi_mem_alloc(struct xgi_mem_heap * heap,
|
static struct xgi_mem_block *xgi_mem_alloc(struct xgi_mem_heap * heap,
|
||||||
unsigned long originalSize)
|
unsigned long originalSize)
|
||||||
{
|
{
|
||||||
struct xgi_mem_block *block, *free_block, *used_block;
|
struct xgi_mem_block *block, *free_block, *used_block;
|
||||||
unsigned long size = (originalSize + PAGE_SIZE - 1) & PAGE_MASK;
|
unsigned long size = (originalSize + PAGE_SIZE - 1) & PAGE_MASK;
|
||||||
|
@ -242,13 +242,15 @@ int xgi_mem_free(struct xgi_mem_heap * heap, unsigned long offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int xgi_fb_alloc(struct xgi_info * info, struct xgi_mem_alloc * alloc,
|
int xgi_alloc(struct xgi_info * info, struct xgi_mem_alloc * alloc,
|
||||||
struct drm_file * filp)
|
struct drm_file * filp)
|
||||||
{
|
{
|
||||||
struct xgi_mem_block *block;
|
struct xgi_mem_block *block;
|
||||||
|
|
||||||
down(&info->fb_sem);
|
down(&info->fb_sem);
|
||||||
block = xgi_mem_alloc(&info->fb_heap, alloc->size);
|
block = xgi_mem_alloc((alloc->location == XGI_MEMLOC_LOCAL)
|
||||||
|
? &info->fb_heap : &info->pcie_heap,
|
||||||
|
alloc->size);
|
||||||
up(&info->fb_sem);
|
up(&info->fb_sem);
|
||||||
|
|
||||||
if (block == NULL) {
|
if (block == NULL) {
|
||||||
|
@ -258,11 +260,14 @@ int xgi_fb_alloc(struct xgi_info * info, struct xgi_mem_alloc * alloc,
|
||||||
} else {
|
} else {
|
||||||
DRM_INFO("Video RAM allocation succeeded: 0x%p\n",
|
DRM_INFO("Video RAM allocation succeeded: 0x%p\n",
|
||||||
(char *)block->offset);
|
(char *)block->offset);
|
||||||
alloc->location = XGI_MEMLOC_LOCAL;
|
|
||||||
alloc->size = block->size;
|
alloc->size = block->size;
|
||||||
alloc->offset = block->offset;
|
alloc->offset = block->offset;
|
||||||
alloc->hw_addr = block->offset;
|
alloc->hw_addr = block->offset;
|
||||||
|
|
||||||
|
if (alloc->location == XGI_MEMLOC_NON_LOCAL) {
|
||||||
|
alloc->hw_addr += info->pcie.base;
|
||||||
|
}
|
||||||
|
|
||||||
block->filp = filp;
|
block->filp = filp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +282,8 @@ int xgi_fb_alloc_ioctl(struct drm_device * dev, void * data,
|
||||||
(struct xgi_mem_alloc *) data;
|
(struct xgi_mem_alloc *) data;
|
||||||
struct xgi_info *info = dev->dev_private;
|
struct xgi_info *info = dev->dev_private;
|
||||||
|
|
||||||
return xgi_fb_alloc(info, alloc, filp);
|
alloc->location = XGI_MEMLOC_LOCAL;
|
||||||
|
return xgi_alloc(info, alloc, filp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -140,34 +140,6 @@ int xgi_pcie_heap_init(struct xgi_info * info)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int xgi_pcie_alloc(struct xgi_info * info, struct xgi_mem_alloc * alloc,
|
|
||||||
struct drm_file * filp)
|
|
||||||
{
|
|
||||||
struct xgi_mem_block *block;
|
|
||||||
|
|
||||||
down(&info->pcie_sem);
|
|
||||||
block = xgi_mem_alloc(&info->pcie_heap, alloc->size);
|
|
||||||
up(&info->pcie_sem);
|
|
||||||
|
|
||||||
if (block == NULL) {
|
|
||||||
alloc->location = XGI_MEMLOC_INVALID;
|
|
||||||
alloc->size = 0;
|
|
||||||
DRM_ERROR("PCIE RAM allocation failed\n");
|
|
||||||
return -ENOMEM;
|
|
||||||
} else {
|
|
||||||
DRM_INFO("PCIE RAM allocation succeeded: offset = 0x%lx\n",
|
|
||||||
block->offset);
|
|
||||||
alloc->location = XGI_MEMLOC_NON_LOCAL;
|
|
||||||
alloc->size = block->size;
|
|
||||||
alloc->hw_addr = block->offset + info->pcie.base;
|
|
||||||
alloc->offset = block->offset;
|
|
||||||
|
|
||||||
block->filp = filp;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int xgi_pcie_alloc_ioctl(struct drm_device * dev, void * data,
|
int xgi_pcie_alloc_ioctl(struct drm_device * dev, void * data,
|
||||||
struct drm_file * filp)
|
struct drm_file * filp)
|
||||||
{
|
{
|
||||||
|
@ -175,7 +147,8 @@ int xgi_pcie_alloc_ioctl(struct drm_device * dev, void * data,
|
||||||
(struct xgi_mem_alloc *) data;
|
(struct xgi_mem_alloc *) data;
|
||||||
struct xgi_info *info = dev->dev_private;
|
struct xgi_info *info = dev->dev_private;
|
||||||
|
|
||||||
return xgi_pcie_alloc(info, alloc, filp);
|
alloc->location = XGI_MEMLOC_NON_LOCAL;
|
||||||
|
return xgi_alloc(info, alloc, filp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue