mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-25 00:10:11 +01:00
Changed all printk to DRM_DEBUG + various cleanup and bugfixes
This commit is contained in:
parent
c69d96fc30
commit
2f2480f94e
16 changed files with 452 additions and 979 deletions
|
|
@ -58,7 +58,7 @@
|
|||
|
||||
#define BEGIN_LP_RING(n) do { \
|
||||
if (I810_VERBOSE) \
|
||||
printk("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \
|
||||
DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \
|
||||
if (dev_priv->ring.space < n*4) i810_wait_ring(dev, n*4, 0); \
|
||||
dev_priv->ring.space -= n*4; \
|
||||
outring = dev_priv->ring.tail; \
|
||||
|
|
@ -67,13 +67,13 @@
|
|||
} while (0)
|
||||
|
||||
#define ADVANCE_LP_RING() do { \
|
||||
if (I810_VERBOSE) printk("ADVANCE_LP_RING\n"); \
|
||||
if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \
|
||||
dev_priv->ring.tail = outring; \
|
||||
I810_WRITE(LP_RING + RING_TAIL, outring); \
|
||||
} while(0)
|
||||
|
||||
#define OUT_RING(n) do { \
|
||||
if (I810_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \
|
||||
if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
|
||||
*(volatile unsigned int *)(virt + outring) = n; \
|
||||
outring += 4; \
|
||||
outring &= ringmask; \
|
||||
|
|
@ -86,13 +86,13 @@ static inline void i810_print_status_page(drm_device_t *dev)
|
|||
u32 *temp = (u32 *)dev_priv->hw_status_page;
|
||||
int i;
|
||||
|
||||
printk( "hw_status: Interrupt Status : %x\n", temp[0]);
|
||||
printk( "hw_status: LpRing Head ptr : %x\n", temp[1]);
|
||||
printk( "hw_status: IRing Head ptr : %x\n", temp[2]);
|
||||
printk( "hw_status: Reserved : %x\n", temp[3]);
|
||||
printk( "hw_status: Driver Counter : %d\n", temp[5]);
|
||||
DRM_DEBUG( "hw_status: Interrupt Status : %x\n", temp[0]);
|
||||
DRM_DEBUG( "hw_status: LpRing Head ptr : %x\n", temp[1]);
|
||||
DRM_DEBUG( "hw_status: IRing Head ptr : %x\n", temp[2]);
|
||||
DRM_DEBUG( "hw_status: Reserved : %x\n", temp[3]);
|
||||
DRM_DEBUG( "hw_status: Driver Counter : %d\n", temp[5]);
|
||||
for(i = 6; i < dma->buf_count + 6; i++) {
|
||||
printk( "buffer status idx : %d used: %d\n", i - 6, temp[i]);
|
||||
DRM_DEBUG( "buffer status idx : %d used: %d\n", i - 6, temp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -209,7 +209,7 @@ static int i810_dma_cleanup(drm_device_t *dev)
|
|||
static int __gettimeinmillis(void)
|
||||
{
|
||||
struct timeval timep;
|
||||
do_gettimeofday(&timep);
|
||||
get_fast_time(&timep);
|
||||
return(timep.tv_sec * 1000) + (timep.tv_usec / 1000);
|
||||
}
|
||||
|
||||
|
|
@ -277,7 +277,7 @@ static int i810_freelist_init(drm_device_t *dev)
|
|||
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
|
||||
|
||||
buf_priv->in_use = hw_status + my_idx;
|
||||
printk("buf_priv->in_use : %p\n", buf_priv->in_use);
|
||||
DRM_DEBUG("buf_priv->in_use : %p\n", buf_priv->in_use);
|
||||
*buf_priv->in_use = I810_BUF_FREE;
|
||||
buf_priv->my_use_idx = my_idx;
|
||||
my_idx += 4;
|
||||
|
|
@ -642,6 +642,10 @@ static int i810_flush_queue(drm_device_t *dev)
|
|||
DECLARE_WAITQUEUE(entry, current);
|
||||
drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
|
||||
int ret = 0;
|
||||
int startTime = 0;
|
||||
int curTime = 0;
|
||||
int timeout_millis = 3000;
|
||||
|
||||
|
||||
if(dev_priv == NULL) {
|
||||
return 0;
|
||||
|
|
@ -651,13 +655,22 @@ static int i810_flush_queue(drm_device_t *dev)
|
|||
add_wait_queue(&dev_priv->flush_queue, &entry);
|
||||
for (;;) {
|
||||
i810_dma_emit_flush(dev);
|
||||
if (atomic_read(&dev_priv->flush_done) == 1) break;
|
||||
schedule_timeout(DRM_LOCK_SLICE);
|
||||
if (atomic_read(&dev_priv->flush_done) == 1) break;
|
||||
curTime = __gettimeinmillis();
|
||||
if (startTime == 0 || curTime < startTime /*wrap case*/) {
|
||||
startTime = curTime;
|
||||
} else if (curTime - startTime > timeout_millis) {
|
||||
DRM_ERROR("lockup\n");
|
||||
goto out_wait_flush;
|
||||
}
|
||||
schedule_timeout(HZ/60);
|
||||
if (signal_pending(current)) {
|
||||
ret = -EINTR; /* Can't restart */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out_wait_flush:
|
||||
current->state = TASK_RUNNING;
|
||||
remove_wait_queue(&dev_priv->flush_queue, &entry);
|
||||
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ MODULE_PARM(i810, "s");
|
|||
|
||||
int init_module(void)
|
||||
{
|
||||
printk("doing i810_init()\n");
|
||||
DRM_DEBUG("doing i810_init()\n");
|
||||
return i810_init();
|
||||
}
|
||||
|
||||
|
|
@ -359,96 +359,6 @@ static int i810_takedown(drm_device_t *dev)
|
|||
/* i810_init is called via init_module at module load time, or via
|
||||
* linux/init/main.c (this is not currently supported). */
|
||||
|
||||
typedef union {
|
||||
void (*free_memory)(agp_memory *);
|
||||
agp_memory *(*allocate_memory)(size_t, u32);
|
||||
int (*bind_memory)(agp_memory *, off_t);
|
||||
int (*unbind_memory)(agp_memory *);
|
||||
void (*enable)(u32);
|
||||
int (*acquire)(void);
|
||||
void (*release)(void);
|
||||
void (*copy_info)(agp_kern_info *);
|
||||
unsigned long address;
|
||||
} drm_agp_func_u;
|
||||
|
||||
typedef struct drm_agp_fill {
|
||||
const char *name;
|
||||
drm_agp_func_u *f;
|
||||
} drm_agp_fill_t;
|
||||
|
||||
static drm_agp_fill_t drm_agp_fill[] = {
|
||||
{ __MODULE_STRING(agp_free_memory),
|
||||
(drm_agp_func_u *)&drm_agp.free_memory },
|
||||
{ __MODULE_STRING(agp_allocate_memory),
|
||||
(drm_agp_func_u *)&drm_agp.allocate_memory },
|
||||
{ __MODULE_STRING(agp_bind_memory),
|
||||
(drm_agp_func_u *)&drm_agp.bind_memory },
|
||||
{ __MODULE_STRING(agp_unbind_memory),
|
||||
(drm_agp_func_u *)&drm_agp.unbind_memory },
|
||||
{ __MODULE_STRING(agp_enable),
|
||||
(drm_agp_func_u *)&drm_agp.enable },
|
||||
{ __MODULE_STRING(agp_backend_acquire),
|
||||
(drm_agp_func_u *)&drm_agp.acquire },
|
||||
{ __MODULE_STRING(agp_backend_release),
|
||||
(drm_agp_func_u *)&drm_agp.release },
|
||||
{ __MODULE_STRING(agp_copy_info),
|
||||
(drm_agp_func_u *)&drm_agp.copy_info },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
drm_agp_head_t *i810_agp_init(void)
|
||||
{
|
||||
drm_agp_fill_t *fill;
|
||||
drm_agp_head_t *head = NULL;
|
||||
int agp_available = 1;
|
||||
|
||||
for (fill = &drm_agp_fill[0]; fill->name; fill++) {
|
||||
char *n = (char *)fill->name;
|
||||
*fill->f = (drm_agp_func_u)get_module_symbol(NULL, n);
|
||||
printk("%s resolves to 0x%08lx\n", n, (*fill->f).address);
|
||||
if (!(*fill->f).address) agp_available = 0;
|
||||
}
|
||||
|
||||
printk("agp_available = %d\n", agp_available);
|
||||
|
||||
if(agp_available == 0) {
|
||||
printk("agp is not available\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (agp_available) {
|
||||
if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS)))
|
||||
return NULL;
|
||||
memset((void *)head, 0, sizeof(*head));
|
||||
(*drm_agp.copy_info)(&head->agp_info);
|
||||
head->memory = NULL;
|
||||
switch (head->agp_info.chipset) {
|
||||
case INTEL_GENERIC: head->chipset = "Intel"; break;
|
||||
case INTEL_LX: head->chipset = "Intel 440LX"; break;
|
||||
case INTEL_BX: head->chipset = "Intel 440BX"; break;
|
||||
case INTEL_GX: head->chipset = "Intel 440GX"; break;
|
||||
case INTEL_I810: head->chipset = "Intel i810"; break;
|
||||
case VIA_GENERIC: head->chipset = "VIA"; break;
|
||||
case VIA_VP3: head->chipset = "VIA VP3"; break;
|
||||
case VIA_MVP3: head->chipset = "VIA MVP3"; break;
|
||||
case VIA_APOLLO_PRO: head->chipset = "VIA Apollo Pro"; break;
|
||||
case SIS_GENERIC: head->chipset = "SiS"; break;
|
||||
case AMD_GENERIC: head->chipset = "AMD"; break;
|
||||
case AMD_IRONGATE: head->chipset = "AMD Irongate"; break;
|
||||
case ALI_GENERIC: head->chipset = "ALi"; break;
|
||||
case ALI_M1541: head->chipset = "ALi M1541"; break;
|
||||
default:
|
||||
}
|
||||
DRM_INFO("AGP %d.%d on %s @ 0x%08lx %dMB\n",
|
||||
head->agp_info.version.major,
|
||||
head->agp_info.version.minor,
|
||||
head->chipset,
|
||||
head->agp_info.aper_base,
|
||||
head->agp_info.aper_size);
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
int i810_init(void)
|
||||
{
|
||||
int retcode;
|
||||
|
|
@ -463,7 +373,7 @@ int i810_init(void)
|
|||
#ifdef MODULE
|
||||
drm_parse_options(i810);
|
||||
#endif
|
||||
printk("doing misc_register\n");
|
||||
DRM_DEBUG("doing misc_register\n");
|
||||
if ((retcode = misc_register(&i810_misc))) {
|
||||
DRM_ERROR("Cannot register \"%s\"\n", I810_NAME);
|
||||
return retcode;
|
||||
|
|
@ -471,22 +381,22 @@ int i810_init(void)
|
|||
dev->device = MKDEV(MISC_MAJOR, i810_misc.minor);
|
||||
dev->name = I810_NAME;
|
||||
|
||||
printk("doing mem init\n");
|
||||
DRM_DEBUG("doing mem init\n");
|
||||
drm_mem_init();
|
||||
printk("doing proc init\n");
|
||||
DRM_DEBUG("doing proc init\n");
|
||||
drm_proc_init(dev);
|
||||
printk("doing agp init\n");
|
||||
dev->agp = i810_agp_init();
|
||||
DRM_DEBUG("doing agp init\n");
|
||||
dev->agp = drm_agp_init();
|
||||
if(dev->agp == NULL) {
|
||||
printk("The i810 drm module requires the agpgart module"
|
||||
" to function correctly\nPlease load the agpgart"
|
||||
" module before you load the i810 module\n");
|
||||
DRM_INFO("The i810 drm module requires the agpgart module"
|
||||
" to function correctly\nPlease load the agpgart"
|
||||
" module before you load the i810 module\n");
|
||||
drm_proc_cleanup();
|
||||
misc_deregister(&i810_misc);
|
||||
i810_takedown(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
printk("doing ctxbitmap init\n");
|
||||
DRM_DEBUG("doing ctxbitmap init\n");
|
||||
if((retcode = drm_ctxbitmap_init(dev))) {
|
||||
DRM_ERROR("Cannot allocate memory for context bitmap.\n");
|
||||
drm_proc_cleanup();
|
||||
|
|
|
|||
|
|
@ -354,95 +354,6 @@ static int mga_takedown(drm_device_t *dev)
|
|||
|
||||
/* mga_init is called via init_module at module load time, or via
|
||||
* linux/init/main.c (this is not currently supported). */
|
||||
typedef union {
|
||||
void (*free_memory)(agp_memory *);
|
||||
agp_memory *(*allocate_memory)(size_t, u32);
|
||||
int (*bind_memory)(agp_memory *, off_t);
|
||||
int (*unbind_memory)(agp_memory *);
|
||||
void (*enable)(u32);
|
||||
int (*acquire)(void);
|
||||
void (*release)(void);
|
||||
void (*copy_info)(agp_kern_info *);
|
||||
unsigned long address;
|
||||
} drm_agp_func_u;
|
||||
|
||||
typedef struct drm_agp_fill {
|
||||
const char *name;
|
||||
drm_agp_func_u *f;
|
||||
} drm_agp_fill_t;
|
||||
|
||||
static drm_agp_fill_t drm_agp_fill[] = {
|
||||
{ __MODULE_STRING(agp_free_memory),
|
||||
(drm_agp_func_u *)&drm_agp.free_memory },
|
||||
{ __MODULE_STRING(agp_allocate_memory),
|
||||
(drm_agp_func_u *)&drm_agp.allocate_memory },
|
||||
{ __MODULE_STRING(agp_bind_memory),
|
||||
(drm_agp_func_u *)&drm_agp.bind_memory },
|
||||
{ __MODULE_STRING(agp_unbind_memory),
|
||||
(drm_agp_func_u *)&drm_agp.unbind_memory },
|
||||
{ __MODULE_STRING(agp_enable),
|
||||
(drm_agp_func_u *)&drm_agp.enable },
|
||||
{ __MODULE_STRING(agp_backend_acquire),
|
||||
(drm_agp_func_u *)&drm_agp.acquire },
|
||||
{ __MODULE_STRING(agp_backend_release),
|
||||
(drm_agp_func_u *)&drm_agp.release },
|
||||
{ __MODULE_STRING(agp_copy_info),
|
||||
(drm_agp_func_u *)&drm_agp.copy_info },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
drm_agp_head_t *mga_agp_init(void)
|
||||
{
|
||||
drm_agp_fill_t *fill;
|
||||
drm_agp_head_t *head = NULL;
|
||||
int agp_available = 1;
|
||||
|
||||
for (fill = &drm_agp_fill[0]; fill->name; fill++) {
|
||||
char *n = (char *)fill->name;
|
||||
*fill->f = (drm_agp_func_u)get_module_symbol(NULL, n);
|
||||
printk("%s resolves to 0x%08lx\n", n, (*fill->f).address);
|
||||
if (!(*fill->f).address) agp_available = 0;
|
||||
}
|
||||
|
||||
printk("agp_available = %d\n", agp_available);
|
||||
|
||||
if(agp_available == 0) {
|
||||
printk("agp is not available\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (agp_available) {
|
||||
if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS)))
|
||||
return NULL;
|
||||
memset((void *)head, 0, sizeof(*head));
|
||||
(*drm_agp.copy_info)(&head->agp_info);
|
||||
head->memory = NULL;
|
||||
switch (head->agp_info.chipset) {
|
||||
case INTEL_GENERIC: head->chipset = "Intel"; break;
|
||||
case INTEL_LX: head->chipset = "Intel 440LX"; break;
|
||||
case INTEL_BX: head->chipset = "Intel 440BX"; break;
|
||||
case INTEL_GX: head->chipset = "Intel 440GX"; break;
|
||||
case INTEL_I810: head->chipset = "Intel i810"; break;
|
||||
case VIA_GENERIC: head->chipset = "VIA"; break;
|
||||
case VIA_VP3: head->chipset = "VIA VP3"; break;
|
||||
case VIA_MVP3: head->chipset = "VIA MVP3"; break;
|
||||
case VIA_APOLLO_PRO: head->chipset = "VIA Apollo Pro"; break;
|
||||
case SIS_GENERIC: head->chipset = "SiS"; break;
|
||||
case AMD_GENERIC: head->chipset = "AMD"; break;
|
||||
case AMD_IRONGATE: head->chipset = "AMD Irongate"; break;
|
||||
case ALI_GENERIC: head->chipset = "ALi"; break;
|
||||
case ALI_M1541: head->chipset = "ALi M1541"; break;
|
||||
default:
|
||||
}
|
||||
DRM_INFO("AGP %d.%d on %s @ 0x%08lx %dMB\n",
|
||||
head->agp_info.version.major,
|
||||
head->agp_info.version.minor,
|
||||
head->chipset,
|
||||
head->agp_info.aper_base,
|
||||
head->agp_info.aper_size);
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
int mga_init(void)
|
||||
{
|
||||
|
|
@ -471,11 +382,11 @@ int mga_init(void)
|
|||
DRM_DEBUG("doing proc init\n");
|
||||
drm_proc_init(dev);
|
||||
DRM_DEBUG("doing agp init\n");
|
||||
dev->agp = mga_agp_init();
|
||||
dev->agp = drm_agp_init();
|
||||
if(dev->agp == NULL) {
|
||||
printk("The mga drm module requires the agpgart module"
|
||||
" to function correctly\nPlease load the agpgart"
|
||||
" module before you load the mga module\n");
|
||||
DRM_DEBUG("The mga drm module requires the agpgart module"
|
||||
" to function correctly\nPlease load the agpgart"
|
||||
" module before you load the mga module\n");
|
||||
drm_proc_cleanup();
|
||||
misc_deregister(&mga_misc);
|
||||
mga_takedown(dev);
|
||||
|
|
|
|||
|
|
@ -277,15 +277,12 @@ drm_agp_head_t *drm_agp_init(void)
|
|||
|
||||
for (fill = &drm_agp_fill[0]; fill->name; fill++) {
|
||||
char *n = (char *)fill->name;
|
||||
#if 0
|
||||
*fill->f = (drm_agp_func_u)get_module_symbol(NULL, n);
|
||||
#endif
|
||||
*fill->f = (drm_agp_func_u)get_module_symbol(NULL, n);
|
||||
printk("%s resolves to 0x%08lx\n", n, (*fill->f).address);
|
||||
DRM_DEBUG("%s resolves to 0x%08lx\n", n, (*fill->f).address);
|
||||
if (!(*fill->f).address) agp_available = 0;
|
||||
}
|
||||
|
||||
printk("agp_available = %d\n", agp_available);
|
||||
DRM_DEBUG("agp_available = %d\n", agp_available);
|
||||
|
||||
if (agp_available) {
|
||||
if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS)))
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ int drm_ctxbitmap_next(drm_device_t *dev)
|
|||
bit = find_first_zero_bit(dev->ctx_bitmap, DRM_MAX_CTXBITMAP);
|
||||
if (bit < DRM_MAX_CTXBITMAP) {
|
||||
set_bit(bit, dev->ctx_bitmap);
|
||||
printk("drm_ctxbitmap_next bit : %d\n", bit);
|
||||
DRM_DEBUG("drm_ctxbitmap_next bit : %d\n", bit);
|
||||
return bit;
|
||||
}
|
||||
return -1;
|
||||
|
|
@ -72,7 +72,7 @@ int drm_ctxbitmap_init(drm_device_t *dev)
|
|||
memset((void *) dev->ctx_bitmap, 0, PAGE_SIZE * 4);
|
||||
for(i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
|
||||
temp = drm_ctxbitmap_next(dev);
|
||||
printk("drm_ctxbitmap_init : %d\n", temp);
|
||||
DRM_DEBUG("drm_ctxbitmap_init : %d\n", temp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ int i810_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
buf->total = alignment;
|
||||
buf->order = order;
|
||||
buf->used = 0;
|
||||
buf->offset = offset; /* Hrm */
|
||||
buf->offset = offset;
|
||||
buf->bus_address = dev->agp->base + agp_offset + offset;
|
||||
buf->address = (void *)(agp_offset + offset + dev->agp->base);
|
||||
buf->next = NULL;
|
||||
|
|
@ -131,8 +131,8 @@ int i810_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
entry->buf_count++;
|
||||
byte_count += PAGE_SIZE << page_order;
|
||||
|
||||
printk(KERN_INFO "buffer %d @ %p\n",
|
||||
entry->buf_count, buf->address);
|
||||
DRM_DEBUG("buffer %d @ %p\n",
|
||||
entry->buf_count, buf->address);
|
||||
}
|
||||
|
||||
dma->buflist = drm_realloc(dma->buflist,
|
||||
|
|
@ -144,13 +144,7 @@ int i810_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
dma->buflist[i] = &entry->buflist[i - dma->buf_count];
|
||||
|
||||
dma->buf_count += entry->buf_count;
|
||||
#if 0
|
||||
printk("dma->buf_count : %d\n", dma->buf_count);
|
||||
#endif
|
||||
dma->byte_count += byte_count;
|
||||
#if 0
|
||||
printk("entry->buf_count : %d\n", entry->buf_count);
|
||||
#endif
|
||||
drm_freelist_create(&entry->freelist, entry->buf_count);
|
||||
for (i = 0; i < entry->buf_count; i++) {
|
||||
drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]);
|
||||
|
|
@ -167,184 +161,10 @@ int i810_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
-EFAULT);
|
||||
|
||||
atomic_dec(&dev->buf_alloc);
|
||||
#if 0
|
||||
printk("count: %d\n", count);
|
||||
printk("order: %d\n", order);
|
||||
printk("size: %d\n", size);
|
||||
printk("agp_offset: %d\n", agp_offset);
|
||||
printk("alignment: %d\n", alignment);
|
||||
printk("page_order: %d\n", page_order);
|
||||
printk("total: %d\n", total);
|
||||
printk("byte_count: %d\n", byte_count);
|
||||
#endif
|
||||
dma->flags = _DRM_DMA_USE_AGP;
|
||||
#if 0
|
||||
printk("dma->flags : %lx\n", dma->flags);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i810_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_desc_t request;
|
||||
int count;
|
||||
int order;
|
||||
int size;
|
||||
int total;
|
||||
int page_order;
|
||||
drm_buf_entry_t *entry;
|
||||
unsigned long page;
|
||||
drm_buf_t *buf;
|
||||
int alignment;
|
||||
unsigned long offset;
|
||||
int i;
|
||||
int byte_count;
|
||||
int page_count;
|
||||
|
||||
if (!dma) return -EINVAL;
|
||||
|
||||
copy_from_user_ret(&request,
|
||||
(drm_buf_desc_t *)arg,
|
||||
sizeof(request),
|
||||
-EFAULT);
|
||||
|
||||
count = request.count;
|
||||
order = drm_order(request.size);
|
||||
size = 1 << order;
|
||||
|
||||
DRM_DEBUG("count = %d, size = %d (%d), order = %d, queue_count = %d\n",
|
||||
request.count, request.size, size, order, dev->queue_count);
|
||||
|
||||
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
|
||||
if (dev->queue_count) return -EBUSY; /* Not while in use */
|
||||
|
||||
alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size;
|
||||
page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
|
||||
total = PAGE_SIZE << page_order;
|
||||
|
||||
spin_lock(&dev->count_lock);
|
||||
if (dev->buf_use) {
|
||||
spin_unlock(&dev->count_lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
atomic_inc(&dev->buf_alloc);
|
||||
spin_unlock(&dev->count_lock);
|
||||
|
||||
down(&dev->struct_sem);
|
||||
entry = &dma->bufs[order];
|
||||
if (entry->buf_count) {
|
||||
up(&dev->struct_sem);
|
||||
atomic_dec(&dev->buf_alloc);
|
||||
return -ENOMEM; /* May only call once for each order */
|
||||
}
|
||||
|
||||
entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
|
||||
DRM_MEM_BUFS);
|
||||
if (!entry->buflist) {
|
||||
up(&dev->struct_sem);
|
||||
atomic_dec(&dev->buf_alloc);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(entry->buflist, 0, count * sizeof(*entry->buflist));
|
||||
|
||||
entry->seglist = drm_alloc(count * sizeof(*entry->seglist),
|
||||
DRM_MEM_SEGS);
|
||||
if (!entry->seglist) {
|
||||
drm_free(entry->buflist,
|
||||
count * sizeof(*entry->buflist),
|
||||
DRM_MEM_BUFS);
|
||||
up(&dev->struct_sem);
|
||||
atomic_dec(&dev->buf_alloc);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(entry->seglist, 0, count * sizeof(*entry->seglist));
|
||||
|
||||
dma->pagelist = drm_realloc(dma->pagelist,
|
||||
dma->page_count * sizeof(*dma->pagelist),
|
||||
(dma->page_count + (count << page_order))
|
||||
* sizeof(*dma->pagelist),
|
||||
DRM_MEM_PAGES);
|
||||
DRM_DEBUG("pagelist: %d entries\n",
|
||||
dma->page_count + (count << page_order));
|
||||
|
||||
|
||||
entry->buf_size = size;
|
||||
entry->page_order = page_order;
|
||||
byte_count = 0;
|
||||
page_count = 0;
|
||||
while (entry->buf_count < count) {
|
||||
if (!(page = drm_alloc_pages(page_order, DRM_MEM_DMA))) break;
|
||||
entry->seglist[entry->seg_count++] = page;
|
||||
for (i = 0; i < (1 << page_order); i++) {
|
||||
DRM_DEBUG("page %d @ 0x%08lx\n",
|
||||
dma->page_count + page_count,
|
||||
page + PAGE_SIZE * i);
|
||||
dma->pagelist[dma->page_count + page_count++]
|
||||
= page + PAGE_SIZE * i;
|
||||
}
|
||||
for (offset = 0;
|
||||
offset + size <= total && entry->buf_count < count;
|
||||
offset += alignment, ++entry->buf_count) {
|
||||
buf = &entry->buflist[entry->buf_count];
|
||||
buf->idx = dma->buf_count + entry->buf_count;
|
||||
buf->total = alignment;
|
||||
buf->order = order;
|
||||
buf->used = 0;
|
||||
buf->offset = (dma->byte_count + byte_count + offset);
|
||||
buf->address = (void *)(page + offset);
|
||||
buf->next = NULL;
|
||||
buf->waiting = 0;
|
||||
buf->pending = 0;
|
||||
init_waitqueue_head(&buf->dma_wait);
|
||||
buf->pid = 0;
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
buf->time_queued = 0;
|
||||
buf->time_dispatched = 0;
|
||||
buf->time_completed = 0;
|
||||
buf->time_freed = 0;
|
||||
#endif
|
||||
DRM_DEBUG("buffer %d @ %p\n",
|
||||
entry->buf_count, buf->address);
|
||||
}
|
||||
byte_count += PAGE_SIZE << page_order;
|
||||
}
|
||||
|
||||
dma->buflist = drm_realloc(dma->buflist,
|
||||
dma->buf_count * sizeof(*dma->buflist),
|
||||
(dma->buf_count + entry->buf_count)
|
||||
* sizeof(*dma->buflist),
|
||||
DRM_MEM_BUFS);
|
||||
for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++)
|
||||
dma->buflist[i] = &entry->buflist[i - dma->buf_count];
|
||||
|
||||
dma->buf_count += entry->buf_count;
|
||||
dma->seg_count += entry->seg_count;
|
||||
dma->page_count += entry->seg_count << page_order;
|
||||
dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
|
||||
|
||||
drm_freelist_create(&entry->freelist, entry->buf_count);
|
||||
for (i = 0; i < entry->buf_count; i++) {
|
||||
drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]);
|
||||
}
|
||||
|
||||
up(&dev->struct_sem);
|
||||
|
||||
request.count = entry->buf_count;
|
||||
request.size = size;
|
||||
|
||||
copy_to_user_ret((drm_buf_desc_t *)arg,
|
||||
&request,
|
||||
sizeof(request),
|
||||
-EFAULT);
|
||||
|
||||
atomic_dec(&dev->buf_alloc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i810_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
|
|
@ -358,7 +178,7 @@ int i810_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
if(request.flags & _DRM_AGP_BUFFER)
|
||||
return i810_addbufs_agp(inode, filp, cmd, arg);
|
||||
else
|
||||
return i810_addbufs_pci(inode, filp, cmd, arg);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int i810_infobufs(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
|
|
@ -532,7 +352,7 @@ int i810_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
spin_lock(&dev->count_lock);
|
||||
if (atomic_read(&dev->buf_alloc)) {
|
||||
spin_unlock(&dev->count_lock);
|
||||
printk("Buzy\n");
|
||||
DRM_DEBUG("Busy\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
++dev->buf_use; /* Can't allocate more after this call */
|
||||
|
|
@ -542,71 +362,66 @@ int i810_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
(drm_buf_map_t *)arg,
|
||||
sizeof(request),
|
||||
-EFAULT);
|
||||
#if 0
|
||||
printk("i810_mapbufs\n");
|
||||
printk("dma->flags : %lx\n", dma->flags);
|
||||
#endif
|
||||
if (request.count >= dma->buf_count) {
|
||||
if(dma->flags & _DRM_DMA_USE_AGP) {
|
||||
drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
|
||||
drm_map_t *map = NULL;
|
||||
|
||||
map = dev->maplist[dev_priv->buffer_map_idx];
|
||||
if (!map) {
|
||||
printk("map is null\n");
|
||||
retcode = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
#if 0
|
||||
printk("map->offset : %lx\n", map->offset);
|
||||
printk("map->size : %lx\n", map->size);
|
||||
printk("map->type : %d\n", map->type);
|
||||
printk("map->flags : %x\n", map->flags);
|
||||
printk("map->handle : %lx\n", map->handle);
|
||||
printk("map->mtrr : %d\n", map->mtrr);
|
||||
#endif
|
||||
virtual = do_mmap(filp, 0, map->size, PROT_READ|PROT_WRITE,
|
||||
MAP_SHARED, (unsigned long)map->offset);
|
||||
} else {
|
||||
DRM_DEBUG("dma->flags : %lx\n", dma->flags);
|
||||
if (request.count >= dma->buf_count) {
|
||||
if(dma->flags & _DRM_DMA_USE_AGP) {
|
||||
drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
|
||||
drm_map_t *map = NULL;
|
||||
|
||||
map = dev->maplist[dev_priv->buffer_map_idx];
|
||||
if (!map) {
|
||||
DRM_DEBUG("map is null\n");
|
||||
retcode = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
DRM_DEBUG("map->offset : %lx\n", map->offset);
|
||||
DRM_DEBUG("map->size : %lx\n", map->size);
|
||||
DRM_DEBUG("map->type : %d\n", map->type);
|
||||
DRM_DEBUG("map->flags : %x\n", map->flags);
|
||||
DRM_DEBUG("map->handle : %lx\n", map->handle);
|
||||
DRM_DEBUG("map->mtrr : %d\n", map->mtrr);
|
||||
virtual = do_mmap(filp, 0, map->size, PROT_READ|PROT_WRITE,
|
||||
MAP_SHARED, (unsigned long)map->offset);
|
||||
} else {
|
||||
virtual = do_mmap(filp, 0, dma->byte_count,
|
||||
PROT_READ|PROT_WRITE, MAP_SHARED, 0);
|
||||
}
|
||||
if (virtual > -1024UL) {
|
||||
/* Real error */
|
||||
printk("mmap error\n");
|
||||
retcode = (signed long)virtual;
|
||||
goto done;
|
||||
}
|
||||
request.virtual = (void *)virtual;
|
||||
|
||||
for (i = 0; i < dma->buf_count; i++) {
|
||||
if (copy_to_user(&request.list[i].idx,
|
||||
&dma->buflist[i]->idx,
|
||||
sizeof(request.list[0].idx))) {
|
||||
retcode = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
if (copy_to_user(&request.list[i].total,
|
||||
&dma->buflist[i]->total,
|
||||
sizeof(request.list[0].total))) {
|
||||
retcode = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
if (copy_to_user(&request.list[i].used,
|
||||
&zero,
|
||||
sizeof(zero))) {
|
||||
retcode = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
address = virtual + dma->buflist[i]->offset;
|
||||
if (copy_to_user(&request.list[i].address,
|
||||
&address,
|
||||
sizeof(address))) {
|
||||
retcode = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (virtual > -1024UL) {
|
||||
/* Real error */
|
||||
DRM_DEBUG("mmap error\n");
|
||||
retcode = (signed long)virtual;
|
||||
goto done;
|
||||
}
|
||||
request.virtual = (void *)virtual;
|
||||
|
||||
for (i = 0; i < dma->buf_count; i++) {
|
||||
if (copy_to_user(&request.list[i].idx,
|
||||
&dma->buflist[i]->idx,
|
||||
sizeof(request.list[0].idx))) {
|
||||
retcode = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
if (copy_to_user(&request.list[i].total,
|
||||
&dma->buflist[i]->total,
|
||||
sizeof(request.list[0].total))) {
|
||||
retcode = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
if (copy_to_user(&request.list[i].used,
|
||||
&zero,
|
||||
sizeof(zero))) {
|
||||
retcode = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
address = virtual + dma->buflist[i]->offset;
|
||||
if (copy_to_user(&request.list[i].address,
|
||||
&address,
|
||||
sizeof(address))) {
|
||||
retcode = -EFAULT;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
done:
|
||||
request.count = dma->buf_count;
|
||||
DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode);
|
||||
|
|
@ -615,8 +430,7 @@ int i810_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
&request,
|
||||
sizeof(request),
|
||||
-EFAULT);
|
||||
#if 0
|
||||
printk("retcode : %d\n", retcode);
|
||||
#endif
|
||||
|
||||
DRM_DEBUG("retcode : %d\n", retcode);
|
||||
return retcode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
static int i810_alloc_queue(drm_device_t *dev)
|
||||
{
|
||||
int temp = drm_ctxbitmap_next(dev);
|
||||
printk("i810_alloc_queue: %d\n", temp);
|
||||
DRM_DEBUG("i810_alloc_queue: %d\n", temp);
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ int i810_context_switch(drm_device_t *dev, int old, int new)
|
|||
dev->ctx_start = get_cycles();
|
||||
#endif
|
||||
|
||||
printk("Context switch from %d to %d\n", old, new);
|
||||
DRM_DEBUG("Context switch from %d to %d\n", old, new);
|
||||
|
||||
if (new == dev->last_context) {
|
||||
clear_bit(0, &dev->context_flag);
|
||||
|
|
@ -104,7 +104,7 @@ int i810_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
drm_ctx_t ctx;
|
||||
int i;
|
||||
|
||||
printk("%d\n", DRM_RESERVED_CONTEXTS);
|
||||
DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
|
||||
copy_from_user_ret(&res, (drm_ctx_res_t *)arg, sizeof(res), -EFAULT);
|
||||
if (res.count >= DRM_RESERVED_CONTEXTS) {
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
|
|
@ -134,11 +134,11 @@ int i810_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
ctx.handle = i810_alloc_queue(dev);
|
||||
}
|
||||
if (ctx.handle == -1) {
|
||||
printk("Not enough free contexts.\n");
|
||||
DRM_DEBUG("Not enough free contexts.\n");
|
||||
/* Should this return -EBUSY instead? */
|
||||
return -ENOMEM;
|
||||
}
|
||||
printk("%d\n", ctx.handle);
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -170,7 +170,7 @@ int i810_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
drm_ctx_t ctx;
|
||||
|
||||
copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
|
||||
printk("%d\n", ctx.handle);
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
return i810_context_switch(dev, dev->last_context, ctx.handle);
|
||||
}
|
||||
|
||||
|
|
@ -182,7 +182,7 @@ int i810_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
drm_ctx_t ctx;
|
||||
|
||||
copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
|
||||
printk("%d\n", ctx.handle);
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
i810_context_switch_complete(dev, ctx.handle);
|
||||
|
||||
return 0;
|
||||
|
|
@ -196,7 +196,7 @@ int i810_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
drm_ctx_t ctx;
|
||||
|
||||
copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
|
||||
printk("%d\n", ctx.handle);
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
if(ctx.handle != DRM_KERNEL_CONTEXT) {
|
||||
drm_ctxbitmap_free(dev, ctx.handle);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
|
||||
#define BEGIN_LP_RING(n) do { \
|
||||
if (I810_VERBOSE) \
|
||||
printk("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \
|
||||
DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \
|
||||
if (dev_priv->ring.space < n*4) i810_wait_ring(dev, n*4, 0); \
|
||||
dev_priv->ring.space -= n*4; \
|
||||
outring = dev_priv->ring.tail; \
|
||||
|
|
@ -67,13 +67,13 @@
|
|||
} while (0)
|
||||
|
||||
#define ADVANCE_LP_RING() do { \
|
||||
if (I810_VERBOSE) printk("ADVANCE_LP_RING\n"); \
|
||||
if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \
|
||||
dev_priv->ring.tail = outring; \
|
||||
I810_WRITE(LP_RING + RING_TAIL, outring); \
|
||||
} while(0)
|
||||
|
||||
#define OUT_RING(n) do { \
|
||||
if (I810_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \
|
||||
if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
|
||||
*(volatile unsigned int *)(virt + outring) = n; \
|
||||
outring += 4; \
|
||||
outring &= ringmask; \
|
||||
|
|
@ -86,13 +86,13 @@ static inline void i810_print_status_page(drm_device_t *dev)
|
|||
u32 *temp = (u32 *)dev_priv->hw_status_page;
|
||||
int i;
|
||||
|
||||
printk( "hw_status: Interrupt Status : %x\n", temp[0]);
|
||||
printk( "hw_status: LpRing Head ptr : %x\n", temp[1]);
|
||||
printk( "hw_status: IRing Head ptr : %x\n", temp[2]);
|
||||
printk( "hw_status: Reserved : %x\n", temp[3]);
|
||||
printk( "hw_status: Driver Counter : %d\n", temp[5]);
|
||||
DRM_DEBUG( "hw_status: Interrupt Status : %x\n", temp[0]);
|
||||
DRM_DEBUG( "hw_status: LpRing Head ptr : %x\n", temp[1]);
|
||||
DRM_DEBUG( "hw_status: IRing Head ptr : %x\n", temp[2]);
|
||||
DRM_DEBUG( "hw_status: Reserved : %x\n", temp[3]);
|
||||
DRM_DEBUG( "hw_status: Driver Counter : %d\n", temp[5]);
|
||||
for(i = 6; i < dma->buf_count + 6; i++) {
|
||||
printk( "buffer status idx : %d used: %d\n", i - 6, temp[i]);
|
||||
DRM_DEBUG( "buffer status idx : %d used: %d\n", i - 6, temp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -209,7 +209,7 @@ static int i810_dma_cleanup(drm_device_t *dev)
|
|||
static int __gettimeinmillis(void)
|
||||
{
|
||||
struct timeval timep;
|
||||
do_gettimeofday(&timep);
|
||||
get_fast_time(&timep);
|
||||
return(timep.tv_sec * 1000) + (timep.tv_usec / 1000);
|
||||
}
|
||||
|
||||
|
|
@ -277,7 +277,7 @@ static int i810_freelist_init(drm_device_t *dev)
|
|||
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
|
||||
|
||||
buf_priv->in_use = hw_status + my_idx;
|
||||
printk("buf_priv->in_use : %p\n", buf_priv->in_use);
|
||||
DRM_DEBUG("buf_priv->in_use : %p\n", buf_priv->in_use);
|
||||
*buf_priv->in_use = I810_BUF_FREE;
|
||||
buf_priv->my_use_idx = my_idx;
|
||||
my_idx += 4;
|
||||
|
|
@ -642,6 +642,10 @@ static int i810_flush_queue(drm_device_t *dev)
|
|||
DECLARE_WAITQUEUE(entry, current);
|
||||
drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
|
||||
int ret = 0;
|
||||
int startTime = 0;
|
||||
int curTime = 0;
|
||||
int timeout_millis = 3000;
|
||||
|
||||
|
||||
if(dev_priv == NULL) {
|
||||
return 0;
|
||||
|
|
@ -651,13 +655,22 @@ static int i810_flush_queue(drm_device_t *dev)
|
|||
add_wait_queue(&dev_priv->flush_queue, &entry);
|
||||
for (;;) {
|
||||
i810_dma_emit_flush(dev);
|
||||
if (atomic_read(&dev_priv->flush_done) == 1) break;
|
||||
schedule_timeout(DRM_LOCK_SLICE);
|
||||
if (atomic_read(&dev_priv->flush_done) == 1) break;
|
||||
curTime = __gettimeinmillis();
|
||||
if (startTime == 0 || curTime < startTime /*wrap case*/) {
|
||||
startTime = curTime;
|
||||
} else if (curTime - startTime > timeout_millis) {
|
||||
DRM_ERROR("lockup\n");
|
||||
goto out_wait_flush;
|
||||
}
|
||||
schedule_timeout(HZ/60);
|
||||
if (signal_pending(current)) {
|
||||
ret = -EINTR; /* Can't restart */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out_wait_flush:
|
||||
current->state = TASK_RUNNING;
|
||||
remove_wait_queue(&dev_priv->flush_queue, &entry);
|
||||
|
||||
|
|
|
|||
110
linux/i810_drv.c
110
linux/i810_drv.c
|
|
@ -130,7 +130,7 @@ MODULE_PARM(i810, "s");
|
|||
|
||||
int init_module(void)
|
||||
{
|
||||
printk("doing i810_init()\n");
|
||||
DRM_DEBUG("doing i810_init()\n");
|
||||
return i810_init();
|
||||
}
|
||||
|
||||
|
|
@ -359,96 +359,6 @@ static int i810_takedown(drm_device_t *dev)
|
|||
/* i810_init is called via init_module at module load time, or via
|
||||
* linux/init/main.c (this is not currently supported). */
|
||||
|
||||
typedef union {
|
||||
void (*free_memory)(agp_memory *);
|
||||
agp_memory *(*allocate_memory)(size_t, u32);
|
||||
int (*bind_memory)(agp_memory *, off_t);
|
||||
int (*unbind_memory)(agp_memory *);
|
||||
void (*enable)(u32);
|
||||
int (*acquire)(void);
|
||||
void (*release)(void);
|
||||
void (*copy_info)(agp_kern_info *);
|
||||
unsigned long address;
|
||||
} drm_agp_func_u;
|
||||
|
||||
typedef struct drm_agp_fill {
|
||||
const char *name;
|
||||
drm_agp_func_u *f;
|
||||
} drm_agp_fill_t;
|
||||
|
||||
static drm_agp_fill_t drm_agp_fill[] = {
|
||||
{ __MODULE_STRING(agp_free_memory),
|
||||
(drm_agp_func_u *)&drm_agp.free_memory },
|
||||
{ __MODULE_STRING(agp_allocate_memory),
|
||||
(drm_agp_func_u *)&drm_agp.allocate_memory },
|
||||
{ __MODULE_STRING(agp_bind_memory),
|
||||
(drm_agp_func_u *)&drm_agp.bind_memory },
|
||||
{ __MODULE_STRING(agp_unbind_memory),
|
||||
(drm_agp_func_u *)&drm_agp.unbind_memory },
|
||||
{ __MODULE_STRING(agp_enable),
|
||||
(drm_agp_func_u *)&drm_agp.enable },
|
||||
{ __MODULE_STRING(agp_backend_acquire),
|
||||
(drm_agp_func_u *)&drm_agp.acquire },
|
||||
{ __MODULE_STRING(agp_backend_release),
|
||||
(drm_agp_func_u *)&drm_agp.release },
|
||||
{ __MODULE_STRING(agp_copy_info),
|
||||
(drm_agp_func_u *)&drm_agp.copy_info },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
drm_agp_head_t *i810_agp_init(void)
|
||||
{
|
||||
drm_agp_fill_t *fill;
|
||||
drm_agp_head_t *head = NULL;
|
||||
int agp_available = 1;
|
||||
|
||||
for (fill = &drm_agp_fill[0]; fill->name; fill++) {
|
||||
char *n = (char *)fill->name;
|
||||
*fill->f = (drm_agp_func_u)get_module_symbol(NULL, n);
|
||||
printk("%s resolves to 0x%08lx\n", n, (*fill->f).address);
|
||||
if (!(*fill->f).address) agp_available = 0;
|
||||
}
|
||||
|
||||
printk("agp_available = %d\n", agp_available);
|
||||
|
||||
if(agp_available == 0) {
|
||||
printk("agp is not available\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (agp_available) {
|
||||
if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS)))
|
||||
return NULL;
|
||||
memset((void *)head, 0, sizeof(*head));
|
||||
(*drm_agp.copy_info)(&head->agp_info);
|
||||
head->memory = NULL;
|
||||
switch (head->agp_info.chipset) {
|
||||
case INTEL_GENERIC: head->chipset = "Intel"; break;
|
||||
case INTEL_LX: head->chipset = "Intel 440LX"; break;
|
||||
case INTEL_BX: head->chipset = "Intel 440BX"; break;
|
||||
case INTEL_GX: head->chipset = "Intel 440GX"; break;
|
||||
case INTEL_I810: head->chipset = "Intel i810"; break;
|
||||
case VIA_GENERIC: head->chipset = "VIA"; break;
|
||||
case VIA_VP3: head->chipset = "VIA VP3"; break;
|
||||
case VIA_MVP3: head->chipset = "VIA MVP3"; break;
|
||||
case VIA_APOLLO_PRO: head->chipset = "VIA Apollo Pro"; break;
|
||||
case SIS_GENERIC: head->chipset = "SiS"; break;
|
||||
case AMD_GENERIC: head->chipset = "AMD"; break;
|
||||
case AMD_IRONGATE: head->chipset = "AMD Irongate"; break;
|
||||
case ALI_GENERIC: head->chipset = "ALi"; break;
|
||||
case ALI_M1541: head->chipset = "ALi M1541"; break;
|
||||
default:
|
||||
}
|
||||
DRM_INFO("AGP %d.%d on %s @ 0x%08lx %dMB\n",
|
||||
head->agp_info.version.major,
|
||||
head->agp_info.version.minor,
|
||||
head->chipset,
|
||||
head->agp_info.aper_base,
|
||||
head->agp_info.aper_size);
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
int i810_init(void)
|
||||
{
|
||||
int retcode;
|
||||
|
|
@ -463,7 +373,7 @@ int i810_init(void)
|
|||
#ifdef MODULE
|
||||
drm_parse_options(i810);
|
||||
#endif
|
||||
printk("doing misc_register\n");
|
||||
DRM_DEBUG("doing misc_register\n");
|
||||
if ((retcode = misc_register(&i810_misc))) {
|
||||
DRM_ERROR("Cannot register \"%s\"\n", I810_NAME);
|
||||
return retcode;
|
||||
|
|
@ -471,22 +381,22 @@ int i810_init(void)
|
|||
dev->device = MKDEV(MISC_MAJOR, i810_misc.minor);
|
||||
dev->name = I810_NAME;
|
||||
|
||||
printk("doing mem init\n");
|
||||
DRM_DEBUG("doing mem init\n");
|
||||
drm_mem_init();
|
||||
printk("doing proc init\n");
|
||||
DRM_DEBUG("doing proc init\n");
|
||||
drm_proc_init(dev);
|
||||
printk("doing agp init\n");
|
||||
dev->agp = i810_agp_init();
|
||||
DRM_DEBUG("doing agp init\n");
|
||||
dev->agp = drm_agp_init();
|
||||
if(dev->agp == NULL) {
|
||||
printk("The i810 drm module requires the agpgart module"
|
||||
" to function correctly\nPlease load the agpgart"
|
||||
" module before you load the i810 module\n");
|
||||
DRM_INFO("The i810 drm module requires the agpgart module"
|
||||
" to function correctly\nPlease load the agpgart"
|
||||
" module before you load the i810 module\n");
|
||||
drm_proc_cleanup();
|
||||
misc_deregister(&i810_misc);
|
||||
i810_takedown(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
printk("doing ctxbitmap init\n");
|
||||
DRM_DEBUG("doing ctxbitmap init\n");
|
||||
if((retcode = drm_ctxbitmap_init(dev))) {
|
||||
DRM_ERROR("Cannot allocate memory for context bitmap.\n");
|
||||
drm_proc_cleanup();
|
||||
|
|
|
|||
|
|
@ -391,14 +391,14 @@ int drm_bind_agp(agp_memory *handle, unsigned int start)
|
|||
{
|
||||
int retcode = -EINVAL;
|
||||
|
||||
printk("drm_bind_agp called\n");
|
||||
DRM_DEBUG("drm_bind_agp called\n");
|
||||
if (!handle) {
|
||||
DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
|
||||
"Attempt to bind NULL AGP handle\n");
|
||||
return retcode;
|
||||
}
|
||||
|
||||
printk("drm_agp.bind_memory : %p\n", drm_agp.bind_memory);
|
||||
DRM_DEBUG("drm_agp.bind_memory : %p\n", drm_agp.bind_memory);
|
||||
if (drm_agp.bind_memory) {
|
||||
if (!(retcode = (*drm_agp.bind_memory)(handle, start))) {
|
||||
spin_lock(&drm_mem_lock);
|
||||
|
|
@ -406,7 +406,7 @@ int drm_bind_agp(agp_memory *handle, unsigned int start)
|
|||
drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_allocated
|
||||
+= handle->page_count << PAGE_SHIFT;
|
||||
spin_unlock(&drm_mem_lock);
|
||||
printk("drm_agp.bind_memory: retcode %d\n", retcode);
|
||||
DRM_DEBUG("drm_agp.bind_memory: retcode %d\n", retcode);
|
||||
return retcode;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
static int mga_alloc_queue(drm_device_t *dev)
|
||||
{
|
||||
int temp = drm_ctxbitmap_next(dev);
|
||||
printk("mga_alloc_queue: %d\n", temp);
|
||||
DRM_DEBUG("mga_alloc_queue: %d\n", temp);
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ int mga_context_switch(drm_device_t *dev, int old, int new)
|
|||
dev->ctx_start = get_cycles();
|
||||
#endif
|
||||
|
||||
printk("Context switch from %d to %d\n", old, new);
|
||||
DRM_DEBUG("Context switch from %d to %d\n", old, new);
|
||||
|
||||
if (new == dev->last_context) {
|
||||
clear_bit(0, &dev->context_flag);
|
||||
|
|
@ -104,7 +104,7 @@ int mga_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
drm_ctx_t ctx;
|
||||
int i;
|
||||
|
||||
printk("%d\n", DRM_RESERVED_CONTEXTS);
|
||||
DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
|
||||
copy_from_user_ret(&res, (drm_ctx_res_t *)arg, sizeof(res), -EFAULT);
|
||||
if (res.count >= DRM_RESERVED_CONTEXTS) {
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
|
|
@ -134,11 +134,11 @@ int mga_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
ctx.handle = mga_alloc_queue(dev);
|
||||
}
|
||||
if (ctx.handle == -1) {
|
||||
printk("Not enough free contexts.\n");
|
||||
DRM_DEBUG("Not enough free contexts.\n");
|
||||
/* Should this return -EBUSY instead? */
|
||||
return -ENOMEM;
|
||||
}
|
||||
printk("%d\n", ctx.handle);
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -170,7 +170,7 @@ int mga_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
drm_ctx_t ctx;
|
||||
|
||||
copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
|
||||
printk("%d\n", ctx.handle);
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
return mga_context_switch(dev, dev->last_context, ctx.handle);
|
||||
}
|
||||
|
||||
|
|
@ -182,7 +182,7 @@ int mga_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
drm_ctx_t ctx;
|
||||
|
||||
copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
|
||||
printk("%d\n", ctx.handle);
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
mga_context_switch_complete(dev, ctx.handle);
|
||||
|
||||
return 0;
|
||||
|
|
@ -196,7 +196,7 @@ int mga_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
drm_ctx_t ctx;
|
||||
|
||||
copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
|
||||
printk("%d\n", ctx.handle);
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
if(ctx.handle != DRM_KERNEL_CONTEXT) {
|
||||
drm_ctxbitmap_free(dev, ctx.handle);
|
||||
}
|
||||
|
|
|
|||
305
linux/mga_dma.c
305
linux/mga_dma.c
|
|
@ -98,13 +98,13 @@ static void mga_flush_write_combine(void)
|
|||
static void mga_freelist_debug(drm_mga_freelist_t *item)
|
||||
{
|
||||
if(item->buf != NULL) {
|
||||
printk("buf index : %d\n", item->buf->idx);
|
||||
DRM_DEBUG("buf index : %d\n", item->buf->idx);
|
||||
} else {
|
||||
printk("Freelist head\n");
|
||||
DRM_DEBUG("Freelist head\n");
|
||||
}
|
||||
printk("item->age : %x\n", item->age);
|
||||
printk("item->next : %p\n", item->next);
|
||||
printk("item->prev : %p\n", item->prev);
|
||||
DRM_DEBUG("item->age : %x\n", item->age);
|
||||
DRM_DEBUG("item->next : %p\n", item->next);
|
||||
DRM_DEBUG("item->prev : %p\n", item->prev);
|
||||
}
|
||||
|
||||
static int mga_freelist_init(drm_device_t *dev)
|
||||
|
|
@ -144,9 +144,9 @@ static int mga_freelist_init(drm_device_t *dev)
|
|||
mga_freelist_debug(item);
|
||||
item = item->next;
|
||||
}
|
||||
printk("Head\n");
|
||||
DRM_DEBUG("Head\n");
|
||||
mga_freelist_debug(dev_priv->head);
|
||||
printk("Tail\n");
|
||||
DRM_DEBUG("Tail\n");
|
||||
mga_freelist_debug(dev_priv->tail);
|
||||
|
||||
return 0;
|
||||
|
|
@ -170,71 +170,64 @@ static void mga_freelist_cleanup(drm_device_t *dev)
|
|||
dev_priv->head = dev_priv->tail = NULL;
|
||||
}
|
||||
|
||||
void mga_wait_usec(int waittime)
|
||||
static int __gettimeinmillis(void)
|
||||
{
|
||||
struct timeval timep;
|
||||
int top_usec = 0;
|
||||
int bot_usec = 0;
|
||||
int i;
|
||||
|
||||
while(1) {
|
||||
do_gettimeofday(&timep);
|
||||
top_usec = timep.tv_usec;
|
||||
if((bot_usec = 0) || (top_usec < bot_usec)) {
|
||||
bot_usec = top_usec;
|
||||
} else if ((top_usec - bot_usec) > waittime) {
|
||||
break;
|
||||
}
|
||||
for(i = 0 ; i < 4096; i++) mga_delay();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void mga_reset_abort(drm_device_t *dev)
|
||||
{
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
u32 temp;
|
||||
u32 reset;
|
||||
|
||||
pci_read_config_dword(dev_priv->device,
|
||||
0x04,
|
||||
&temp);
|
||||
reset = temp;
|
||||
reset &= 0x38000000;
|
||||
if(reset != 0) {
|
||||
/* Do a softreset */
|
||||
DRM_ERROR("Doing a soft reset : reset %x\n", reset);
|
||||
MGA_WRITE(0x1e40, 0x00000001);
|
||||
mga_wait_usec(10);
|
||||
MGA_WRITE(0x1e40, 0x00000000);
|
||||
pci_write_config_dword(dev_priv->device,
|
||||
0x04,
|
||||
temp);
|
||||
}
|
||||
struct timeval timep;
|
||||
get_fast_time(&timep);
|
||||
return(timep.tv_sec * 1000) + (timep.tv_usec / 1000);
|
||||
}
|
||||
|
||||
/* Frees dispatch lock */
|
||||
static inline void mga_dma_quiescent(drm_device_t *dev)
|
||||
{
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
__volatile__ unsigned int *status =
|
||||
(__volatile__ unsigned int *)dev_priv->status_page;
|
||||
|
||||
while(1) {
|
||||
if(!test_and_set_bit(0, &dev_priv->dispatch_lock)) {
|
||||
break;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
__volatile__ unsigned int *status =
|
||||
(__volatile__ unsigned int *)dev_priv->status_page;
|
||||
int startTime = 0;
|
||||
int curTime = 0;
|
||||
int timeout_millis = 3000;
|
||||
int i;
|
||||
|
||||
while(1) {
|
||||
if(!test_and_set_bit(0, &dev_priv->dispatch_lock)) {
|
||||
break;
|
||||
}
|
||||
curTime = __gettimeinmillis();
|
||||
if (startTime == 0 || curTime < startTime /*wrap case*/) {
|
||||
startTime = curTime;
|
||||
} else if (curTime - startTime > timeout_millis) {
|
||||
DRM_ERROR("irqs: %d wanted %d\n",
|
||||
atomic_read(&dev->total_irq),
|
||||
atomic_read(&dma->total_lost));
|
||||
DRM_ERROR("lockup\n");
|
||||
goto out_nolock;
|
||||
}
|
||||
for (i = 0 ; i < 2000 ; i++) mga_delay();
|
||||
}
|
||||
|
||||
DRM_DEBUG("quiescent status : %x\n", MGA_READ(MGAREG_STATUS));
|
||||
mga_reset_abort(dev);
|
||||
while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) ;
|
||||
DRM_DEBUG("status[1] : %x last_sync_tag : %x\n", status[1],
|
||||
dev_priv->last_sync_tag);
|
||||
sarea_priv->dirty |= MGA_DMA_FLUSH;
|
||||
clear_bit(0, &dev_priv->dispatch_lock);
|
||||
startTime = 0;
|
||||
|
||||
DRM_DEBUG("quiescent status : %x\n", MGA_READ(MGAREG_STATUS));
|
||||
while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) {
|
||||
curTime = __gettimeinmillis();
|
||||
if (startTime == 0 || curTime < startTime /*wrap case*/) {
|
||||
startTime = curTime;
|
||||
} else if (curTime - startTime > timeout_millis) {
|
||||
DRM_ERROR("irqs: %d wanted %d\n",
|
||||
atomic_read(&dev->total_irq),
|
||||
atomic_read(&dma->total_lost));
|
||||
DRM_ERROR("lockup\n");
|
||||
goto out_status;
|
||||
}
|
||||
for (i = 0 ; i < 2000 ; i++) mga_delay();
|
||||
}
|
||||
DRM_DEBUG("status[1] : %x last_sync_tag : %x\n", status[1],
|
||||
dev_priv->last_sync_tag);
|
||||
sarea_priv->dirty |= MGA_DMA_FLUSH;
|
||||
out_status:
|
||||
clear_bit(0, &dev_priv->dispatch_lock);
|
||||
out_nolock:
|
||||
}
|
||||
|
||||
#define FREELIST_INITIAL (MGA_DMA_BUF_NR * 2)
|
||||
|
|
@ -394,36 +387,68 @@ static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init)
|
|||
|
||||
void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim)
|
||||
{
|
||||
drm_mga_private_t *dev_priv = dev->dev_private;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
int use_agp = PDEA_pagpxfer_enable;
|
||||
PRIMLOCALS;
|
||||
drm_mga_private_t *dev_priv = dev->dev_private;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
int use_agp = PDEA_pagpxfer_enable;
|
||||
int startTime = 0;
|
||||
int curTime = 0;
|
||||
int timeout_millis = 3000;
|
||||
int i;
|
||||
PRIMLOCALS;
|
||||
|
||||
dev_priv->last_sync_tag = mga_create_sync_tag(dev);
|
||||
dev_priv->last_prim = prim;
|
||||
|
||||
dev_priv->last_sync_tag = mga_create_sync_tag(dev);
|
||||
/* We never check for overflow, b/c there is always room */
|
||||
PRIMPTR(prim);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag);
|
||||
PRIMOUTREG( MGAREG_SOFTRAP, 0);
|
||||
PRIMFINISH(prim);
|
||||
|
||||
/* We never check for overflow, b/c there is always room */
|
||||
PRIMPTR(prim);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag);
|
||||
PRIMOUTREG( MGAREG_SOFTRAP, prim->idx << 2);
|
||||
PRIMFINISH(prim);
|
||||
|
||||
if(sarea_priv->dirty & MGA_DMA_FLUSH) {
|
||||
/* This needs to be optimized so that it only happens
|
||||
* when the Xserver actually did 2d rendering */
|
||||
DRM_DEBUG("Dma top flush\n");
|
||||
while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) ;
|
||||
sarea_priv->dirty &= ~(MGA_DMA_FLUSH);
|
||||
if(sarea_priv->dirty & MGA_DMA_FLUSH) {
|
||||
DRM_DEBUG("Dma top flush\n");
|
||||
while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) {
|
||||
curTime = __gettimeinmillis();
|
||||
if (startTime == 0 || curTime < startTime /*wrap case*/) {
|
||||
startTime = curTime;
|
||||
} else if (curTime - startTime > timeout_millis) {
|
||||
DRM_ERROR("irqs: %d wanted %d\n",
|
||||
atomic_read(&dev->total_irq),
|
||||
atomic_read(&dma->total_lost));
|
||||
DRM_ERROR("lockup in fire primary (Dma Top Flush)\n");
|
||||
goto out_prim_wait;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < 4096 ; i++) mga_delay();
|
||||
}
|
||||
sarea_priv->dirty &= ~(MGA_DMA_FLUSH);
|
||||
} else {
|
||||
DRM_DEBUG("Status wait\n");
|
||||
while((MGA_READ(MGAREG_STATUS) & 0x00020001) != 0x00020000) ;
|
||||
while((MGA_READ(MGAREG_STATUS) & 0x00020001) != 0x00020000) {
|
||||
curTime = __gettimeinmillis();
|
||||
if (startTime == 0 || curTime < startTime /*wrap case*/) {
|
||||
startTime = curTime;
|
||||
} else if (curTime - startTime > timeout_millis) {
|
||||
DRM_ERROR("irqs: %d wanted %d\n",
|
||||
atomic_read(&dev->total_irq),
|
||||
atomic_read(&dma->total_lost));
|
||||
DRM_ERROR("lockup in fire primary (Status Wait)\n");
|
||||
goto out_prim_wait;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < 4096 ; i++) mga_delay();
|
||||
}
|
||||
}
|
||||
|
||||
mga_flush_write_combine();
|
||||
atomic_inc(&dev_priv->pending_bufs);
|
||||
MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
|
||||
MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp);
|
||||
|
||||
mga_flush_write_combine();
|
||||
atomic_inc(&dev_priv->pending_bufs);
|
||||
atomic_inc(&dma->total_lost);
|
||||
MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
|
||||
MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp);
|
||||
out_prim_wait:
|
||||
}
|
||||
|
||||
int mga_advance_primary(drm_device_t *dev)
|
||||
|
|
@ -452,7 +477,7 @@ int mga_advance_primary(drm_device_t *dev)
|
|||
if(!test_and_set_bit(0, &prim_buffer->in_use)) break;
|
||||
atomic_inc(&dev->total_sleeps);
|
||||
atomic_inc(&dma->total_missed_sched);
|
||||
schedule();
|
||||
schedule_timeout(HZ/60);
|
||||
if (signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
break;
|
||||
|
|
@ -554,40 +579,43 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
|
|||
}
|
||||
|
||||
clear_bit(0, &dev->dma_flag);
|
||||
wake_up_interruptible(&dev_priv->wait_queue);
|
||||
if(atomic_read(&dev_priv->in_flush) == 1 &&
|
||||
dev_priv->next_prim->num_dwords == 0) {
|
||||
/* Everything is on the hardware */
|
||||
atomic_set(&dev_priv->in_flush, 0);
|
||||
wake_up_interruptible(&dev_priv->flush_queue);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mga_dma_service(int irq, void *device, struct pt_regs *regs)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)device;
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_mga_prim_buf_t *last_prim_buffer;
|
||||
int softrap_idx;
|
||||
int next_idx;
|
||||
__volatile__ unsigned int *status =
|
||||
(__volatile__ unsigned int *)dev_priv->status_page;
|
||||
|
||||
softrap_idx = MGA_READ(MGAREG_SECADDRESS);
|
||||
atomic_inc(&dev->total_irq);
|
||||
drm_device_t *dev = (drm_device_t *)device;
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_mga_prim_buf_t *last_prim_buffer;
|
||||
int next_idx;
|
||||
__volatile__ unsigned int *status =
|
||||
(__volatile__ unsigned int *)dev_priv->status_page;
|
||||
|
||||
atomic_inc(&dev->total_irq);
|
||||
MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
|
||||
softrap_idx = softrap_idx >> 2;
|
||||
DRM_DEBUG("softrap_idx : %d\n", softrap_idx);
|
||||
next_idx = softrap_idx + 1;
|
||||
if(next_idx >= MGA_NUM_PRIM_BUFS) {
|
||||
next_idx = 0;
|
||||
}
|
||||
dev_priv->next_prim = dev_priv->prim_bufs[next_idx];
|
||||
last_prim_buffer = dev_priv->prim_bufs[softrap_idx];
|
||||
dev_priv->last_prim = last_prim_buffer;
|
||||
last_prim_buffer->num_dwords = 0;
|
||||
last_prim_buffer = dev_priv->last_prim;
|
||||
next_idx = last_prim_buffer->idx + 1;
|
||||
if(next_idx >= MGA_NUM_PRIM_BUFS) {
|
||||
next_idx = 0;
|
||||
}
|
||||
dev_priv->next_prim = dev_priv->prim_bufs[next_idx];
|
||||
last_prim_buffer->num_dwords = 0;
|
||||
last_prim_buffer->sec_used = 0;
|
||||
clear_bit(0, &last_prim_buffer->in_use);
|
||||
last_prim_buffer->num_dwords = 0;
|
||||
last_prim_buffer->sec_used = 0;
|
||||
clear_bit(0, &last_prim_buffer->in_use);
|
||||
clear_bit(0, &last_prim_buffer->swap_pending);
|
||||
clear_bit(0, &dev_priv->dispatch_lock);
|
||||
atomic_dec(&dev_priv->pending_bufs);
|
||||
|
||||
dev_priv->sarea_priv->last_dispatch = status[1];
|
||||
|
||||
queue_task(&dev->tq, &tq_immediate);
|
||||
mark_bh(IMMEDIATE_BH);
|
||||
}
|
||||
|
|
@ -598,13 +626,6 @@ static void mga_dma_task_queue(void *device)
|
|||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
|
||||
mga_dma_schedule(dev, 0);
|
||||
wake_up_interruptible(&dev_priv->wait_queue);
|
||||
if(atomic_read(&dev_priv->in_flush) == 1 &&
|
||||
dev_priv->next_prim->num_dwords == 0) {
|
||||
/* Everything is on the hardware */
|
||||
atomic_set(&dev_priv->in_flush, 0);
|
||||
wake_up_interruptible(&dev_priv->flush_queue);
|
||||
}
|
||||
}
|
||||
|
||||
int mga_dma_cleanup(drm_device_t *dev)
|
||||
|
|
@ -809,15 +830,6 @@ int mga_dma_init(struct inode *inode, struct file *filp,
|
|||
|
||||
return -EINVAL;
|
||||
}
|
||||
#if 0
|
||||
static int __gettimeinmillis(void)
|
||||
{
|
||||
struct timeval timep;
|
||||
do_gettimeofday(&timep);
|
||||
return(timep.tv_sec * 1000) + (timep.tv_usec / 1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int mga_irq_install(drm_device_t *dev, int irq)
|
||||
{
|
||||
|
|
@ -919,10 +931,7 @@ static int mga_flush_queue(drm_device_t *dev)
|
|||
mga_dma_schedule(dev, 0);
|
||||
if (atomic_read(&dev_priv->in_flush) == 0) break;
|
||||
atomic_inc(&dev->total_sleeps);
|
||||
#if 0
|
||||
schedule_timeout(HZ/60);
|
||||
#endif
|
||||
schedule();
|
||||
if (signal_pending(current)) {
|
||||
ret = -EINTR; /* Can't restart */
|
||||
break;
|
||||
|
|
@ -988,19 +997,6 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
*/
|
||||
|
||||
if (!ret) {
|
||||
#if 0
|
||||
if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)
|
||||
== lock.context && _DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock)) {
|
||||
long j = jiffies - dev->lock.lock_time;
|
||||
|
||||
if (j > 0 && j <= DRM_LOCK_SLICE) {
|
||||
/* Can't take lock if we just had it and
|
||||
there is contention. */
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule_timeout(j);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
add_wait_queue(&dev->lock.lock_queue, &entry);
|
||||
for (;;) {
|
||||
if (!dev->lock.hw_lock) {
|
||||
|
|
@ -1045,13 +1041,18 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
int mga_flush_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_lock_t lock;
|
||||
|
||||
copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
|
||||
|
||||
DRM_DEBUG("mga_flush_ioctl\n");
|
||||
atomic_inc(&dma->total_lost);
|
||||
mga_flush_queue(dev);
|
||||
return 0;
|
||||
if(lock.flags & _DRM_LOCK_FLUSH || lock.flags & _DRM_LOCK_FLUSH_ALL) {
|
||||
mga_flush_queue(dev);
|
||||
}
|
||||
if(lock.flags & _DRM_LOCK_QUIESCENT) {
|
||||
mga_dma_quiescent(dev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ if( (tmp_buf->max_dwords - tmp_buf->num_dwords) < length || \
|
|||
drm_mga_prim_buf_t *tmp_buf = \
|
||||
dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
|
||||
if(MGA_VERBOSE) \
|
||||
printk("PRIMGETPTR in %s\n", __FUNCTION__); \
|
||||
DRM_DEBUG("PRIMGETPTR in %s\n", __FUNCTION__); \
|
||||
dma_ptr = tmp_buf->current_dma_ptr; \
|
||||
num_dwords = tmp_buf->num_dwords; \
|
||||
phys_head = tmp_buf->phys_head; \
|
||||
|
|
@ -64,7 +64,7 @@ outcount = 0; \
|
|||
|
||||
#define PRIMPTR(prim_buf) do { \
|
||||
if(MGA_VERBOSE) \
|
||||
printk("PRIMPTR in %s\n", __FUNCTION__); \
|
||||
DRM_DEBUG("PRIMPTR in %s\n", __FUNCTION__); \
|
||||
dma_ptr = prim_buf->current_dma_ptr; \
|
||||
num_dwords = prim_buf->num_dwords; \
|
||||
phys_head = prim_buf->phys_head; \
|
||||
|
|
@ -73,9 +73,9 @@ outcount = 0; \
|
|||
|
||||
#define PRIMFINISH(prim_buf) do { \
|
||||
if (MGA_VERBOSE) { \
|
||||
printk(KERN_INFO "PRIMFINISH in %s\n", __FUNCTION__); \
|
||||
DRM_DEBUG( "PRIMFINISH in %s\n", __FUNCTION__); \
|
||||
if (outcount & 3) \
|
||||
printk(KERN_INFO " --- truncation\n"); \
|
||||
DRM_DEBUG(" --- truncation\n"); \
|
||||
} \
|
||||
prim_buf->num_dwords = num_dwords; \
|
||||
prim_buf->current_dma_ptr = dma_ptr; \
|
||||
|
|
@ -85,9 +85,9 @@ outcount = 0; \
|
|||
drm_mga_prim_buf_t *tmp_buf = \
|
||||
dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
|
||||
if (MGA_VERBOSE) { \
|
||||
printk(KERN_INFO "PRIMADVANCE in %s\n", __FUNCTION__); \
|
||||
DRM_DEBUG("PRIMADVANCE in %s\n", __FUNCTION__); \
|
||||
if (outcount & 3) \
|
||||
printk(KERN_INFO " --- truncation\n"); \
|
||||
DRM_DEBUG(" --- truncation\n"); \
|
||||
} \
|
||||
tmp_buf->num_dwords = num_dwords; \
|
||||
tmp_buf->current_dma_ptr = dma_ptr; \
|
||||
|
|
@ -103,8 +103,7 @@ drm_mga_prim_buf_t *tmp_buf = \
|
|||
tempIndex[outcount]=ADRINDEX(reg); \
|
||||
dma_ptr[1+outcount] = val; \
|
||||
if (MGA_VERBOSE) \
|
||||
printk(KERN_INFO \
|
||||
" PRIMOUT %d: 0x%x -- 0x%x\n", \
|
||||
DRM_DEBUG(" PRIMOUT %d: 0x%x -- 0x%x\n", \
|
||||
num_dwords + 1 + outcount, ADRINDEX(reg), val); \
|
||||
if( ++outcount == 4) { \
|
||||
outcount = 0; \
|
||||
|
|
@ -127,10 +126,4 @@ drm_mga_prim_buf_t *tmp_buf = \
|
|||
DC_pattern_disable | DC_transc_disable | \
|
||||
DC_clipdis_enable) \
|
||||
|
||||
#define MGA_ILOAD_CMD (DC_opcod_iload | DC_atype_rpl | \
|
||||
DC_linear_linear | DC_bltmod_bfcol | \
|
||||
(0xC << DC_bop_SHIFT) | DC_sgnzero_enable | \
|
||||
DC_shftzero_enable | DC_clipdis_enable)
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -252,17 +252,14 @@ typedef struct {
|
|||
int flags;
|
||||
} drm_mga_clear_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int idx;
|
||||
} drm_mga_swap_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned int destOrg;
|
||||
unsigned int mAccess;
|
||||
unsigned int pitch;
|
||||
xf86drmClipRectRec texture;
|
||||
int idx;
|
||||
unsigned int destOrg;
|
||||
int idx;
|
||||
int length;
|
||||
} drm_mga_iload_t;
|
||||
|
||||
|
||||
|
|
@ -287,6 +284,6 @@ typedef struct {
|
|||
#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t)
|
||||
#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t)
|
||||
#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t)
|
||||
#define DRM_IOCTL_MGA_FLUSH DRM_IO ( 0x45 )
|
||||
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t )
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -354,95 +354,6 @@ static int mga_takedown(drm_device_t *dev)
|
|||
|
||||
/* mga_init is called via init_module at module load time, or via
|
||||
* linux/init/main.c (this is not currently supported). */
|
||||
typedef union {
|
||||
void (*free_memory)(agp_memory *);
|
||||
agp_memory *(*allocate_memory)(size_t, u32);
|
||||
int (*bind_memory)(agp_memory *, off_t);
|
||||
int (*unbind_memory)(agp_memory *);
|
||||
void (*enable)(u32);
|
||||
int (*acquire)(void);
|
||||
void (*release)(void);
|
||||
void (*copy_info)(agp_kern_info *);
|
||||
unsigned long address;
|
||||
} drm_agp_func_u;
|
||||
|
||||
typedef struct drm_agp_fill {
|
||||
const char *name;
|
||||
drm_agp_func_u *f;
|
||||
} drm_agp_fill_t;
|
||||
|
||||
static drm_agp_fill_t drm_agp_fill[] = {
|
||||
{ __MODULE_STRING(agp_free_memory),
|
||||
(drm_agp_func_u *)&drm_agp.free_memory },
|
||||
{ __MODULE_STRING(agp_allocate_memory),
|
||||
(drm_agp_func_u *)&drm_agp.allocate_memory },
|
||||
{ __MODULE_STRING(agp_bind_memory),
|
||||
(drm_agp_func_u *)&drm_agp.bind_memory },
|
||||
{ __MODULE_STRING(agp_unbind_memory),
|
||||
(drm_agp_func_u *)&drm_agp.unbind_memory },
|
||||
{ __MODULE_STRING(agp_enable),
|
||||
(drm_agp_func_u *)&drm_agp.enable },
|
||||
{ __MODULE_STRING(agp_backend_acquire),
|
||||
(drm_agp_func_u *)&drm_agp.acquire },
|
||||
{ __MODULE_STRING(agp_backend_release),
|
||||
(drm_agp_func_u *)&drm_agp.release },
|
||||
{ __MODULE_STRING(agp_copy_info),
|
||||
(drm_agp_func_u *)&drm_agp.copy_info },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
drm_agp_head_t *mga_agp_init(void)
|
||||
{
|
||||
drm_agp_fill_t *fill;
|
||||
drm_agp_head_t *head = NULL;
|
||||
int agp_available = 1;
|
||||
|
||||
for (fill = &drm_agp_fill[0]; fill->name; fill++) {
|
||||
char *n = (char *)fill->name;
|
||||
*fill->f = (drm_agp_func_u)get_module_symbol(NULL, n);
|
||||
printk("%s resolves to 0x%08lx\n", n, (*fill->f).address);
|
||||
if (!(*fill->f).address) agp_available = 0;
|
||||
}
|
||||
|
||||
printk("agp_available = %d\n", agp_available);
|
||||
|
||||
if(agp_available == 0) {
|
||||
printk("agp is not available\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (agp_available) {
|
||||
if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS)))
|
||||
return NULL;
|
||||
memset((void *)head, 0, sizeof(*head));
|
||||
(*drm_agp.copy_info)(&head->agp_info);
|
||||
head->memory = NULL;
|
||||
switch (head->agp_info.chipset) {
|
||||
case INTEL_GENERIC: head->chipset = "Intel"; break;
|
||||
case INTEL_LX: head->chipset = "Intel 440LX"; break;
|
||||
case INTEL_BX: head->chipset = "Intel 440BX"; break;
|
||||
case INTEL_GX: head->chipset = "Intel 440GX"; break;
|
||||
case INTEL_I810: head->chipset = "Intel i810"; break;
|
||||
case VIA_GENERIC: head->chipset = "VIA"; break;
|
||||
case VIA_VP3: head->chipset = "VIA VP3"; break;
|
||||
case VIA_MVP3: head->chipset = "VIA MVP3"; break;
|
||||
case VIA_APOLLO_PRO: head->chipset = "VIA Apollo Pro"; break;
|
||||
case SIS_GENERIC: head->chipset = "SiS"; break;
|
||||
case AMD_GENERIC: head->chipset = "AMD"; break;
|
||||
case AMD_IRONGATE: head->chipset = "AMD Irongate"; break;
|
||||
case ALI_GENERIC: head->chipset = "ALi"; break;
|
||||
case ALI_M1541: head->chipset = "ALi M1541"; break;
|
||||
default:
|
||||
}
|
||||
DRM_INFO("AGP %d.%d on %s @ 0x%08lx %dMB\n",
|
||||
head->agp_info.version.major,
|
||||
head->agp_info.version.minor,
|
||||
head->chipset,
|
||||
head->agp_info.aper_base,
|
||||
head->agp_info.aper_size);
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
int mga_init(void)
|
||||
{
|
||||
|
|
@ -471,11 +382,11 @@ int mga_init(void)
|
|||
DRM_DEBUG("doing proc init\n");
|
||||
drm_proc_init(dev);
|
||||
DRM_DEBUG("doing agp init\n");
|
||||
dev->agp = mga_agp_init();
|
||||
dev->agp = drm_agp_init();
|
||||
if(dev->agp == NULL) {
|
||||
printk("The mga drm module requires the agpgart module"
|
||||
" to function correctly\nPlease load the agpgart"
|
||||
" module before you load the mga module\n");
|
||||
DRM_DEBUG("The mga drm module requires the agpgart module"
|
||||
" to function correctly\nPlease load the agpgart"
|
||||
" module before you load the mga module\n");
|
||||
drm_proc_cleanup();
|
||||
misc_deregister(&mga_misc);
|
||||
mga_takedown(dev);
|
||||
|
|
|
|||
|
|
@ -39,35 +39,23 @@
|
|||
|
||||
static void mgaEmitClipRect( drm_mga_private_t *dev_priv, xf86drmClipRectRec *box )
|
||||
{
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
unsigned int *regs = sarea_priv->ContextState;
|
||||
PRIMLOCALS;
|
||||
|
||||
/* This takes a max of 10 dwords */
|
||||
/* This takes 10 dwords */
|
||||
PRIMGETPTR( dev_priv );
|
||||
|
||||
/* Force reset of dwgctl (eliminates clip disable) */
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0 );
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0 );
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0 );
|
||||
PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
|
||||
|
||||
/* JC: The G400 seems to have an issue with the second WARP
|
||||
* not stalling clipper register writes. This bothers me, but
|
||||
* the only way I could get it to never clip the last triangle
|
||||
* under any circumstances is by inserting TWO dwgsync
|
||||
* commands.
|
||||
*
|
||||
* KW: Additionally the mga seems to be able to get itself
|
||||
* into a wierd state where it ignores cliprects for every
|
||||
* *second* triangle... I don't know what provokes this, but
|
||||
* I have seen it flip between 'correct' and 'wierd' modes and
|
||||
* back without stopping or restarting either the X server or
|
||||
* the 3d apps themselves.
|
||||
*/
|
||||
if (dev_priv->chipset == MGA_CARD_TYPE_G400 && 0) {
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0 );
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0 );
|
||||
PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag - 1 );
|
||||
PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag - 1 );
|
||||
}
|
||||
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0 );
|
||||
PRIMOUTREG( MGAREG_CXBNDRY, ((box->x2)<<16)|(box->x1) );
|
||||
PRIMOUTREG( MGAREG_YTOP, box->y1 * dev_priv->stride/2 );
|
||||
PRIMOUTREG( MGAREG_YBOT, box->y2 * dev_priv->stride/2 );
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0 );
|
||||
|
||||
PRIMADVANCE( dev_priv );
|
||||
}
|
||||
|
|
@ -425,71 +413,63 @@ static int mgaVerifyState( drm_mga_private_t *dev_priv )
|
|||
return rv == 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* This is very broken */
|
||||
|
||||
static void mga_dma_dispatch_tex_blit(drm_device_t *dev, drm_buf_t *buf, u16 x1,
|
||||
u16 x2, u16 y1, u16 y2, unsigned int destOrg,
|
||||
unsigned int mAccess, unsigned int pitch)
|
||||
static int mgaVerifyIload( drm_mga_private_t *dev_priv,
|
||||
unsigned long bus_address,
|
||||
unsigned int dstOrg, int length )
|
||||
{
|
||||
int use_agp = PDEA_pagpxfer_enable;
|
||||
drm_mga_private_t *dev_priv = dev->dev_private;
|
||||
drm_mga_buf_priv_t *buf_priv = buf->dev_private;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
unsigned long address = (unsigned long)buf->bus_address;
|
||||
int length;
|
||||
int width, height;
|
||||
int texperdword = 0;
|
||||
PRIMLOCALS;
|
||||
|
||||
switch((maccess & 0x00000003)) {
|
||||
case 0:
|
||||
texperdword = 4;
|
||||
break;
|
||||
case 1:
|
||||
texperdword = 2;
|
||||
break;
|
||||
case 2:
|
||||
texperdword = 1;
|
||||
break;
|
||||
if(dstOrg < dev_priv->textureOffset ||
|
||||
dstOrg + length >
|
||||
(dev_priv->textureOffset + dev_priv->textureSize)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
length = (y2 - y1) * (x2 - x1) / texperdword;
|
||||
|
||||
x2 = (x2 + (texperdword - 1)) & ~(texperdword - 1);
|
||||
x1 = (x1 + (texperdword - 1)) & ~(texperdword - 1);
|
||||
width = x2 - x1;
|
||||
height = y2 - y1;
|
||||
|
||||
PRIMRESET(dev_priv);
|
||||
PRIMGETPTR(dev_priv);
|
||||
PRIMOUTREG(MGAREG_DSTORG, dstorg);
|
||||
PRIMOUTREG(MGAREG_MACCESS, maccess);
|
||||
PRIMOUTREG(MGAREG_PITCH, pitch);
|
||||
PRIMOUTREG(MGAREG_YDSTLEN, (y1 << 16) | height);
|
||||
|
||||
PRIMOUTREG(MGAREG_FXBNDRY, ((x1+width-1) << 16) | x1);
|
||||
PRIMOUTREG(MGAREG_AR0, width * height - 1);
|
||||
PRIMOUTREG(MGAREG_AR3, 0 );
|
||||
PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, MGA_ILOAD_CMD);
|
||||
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_SRCORG, ((__u32)address) | TT_BLIT);
|
||||
PRIMOUTREG(MGAREG_SECEND, ((__u32)(address + length)) | use_agp);
|
||||
|
||||
PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset);
|
||||
PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess);
|
||||
PRIMOUTREG(MGAREG_PITCH, dev_priv->stride);
|
||||
PRIMOUTREG(MGAREG_AR0, 0 );
|
||||
|
||||
PRIMOUTREG(MGAREG_AR3, 0 );
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_SOFTRAP, 0);
|
||||
PRIMADVANCE(dev_priv);
|
||||
if(length % 64) {
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This copies a 64 byte aligned agp region to the frambuffer
|
||||
* with a standard blit, the ioctl needs to do checking */
|
||||
|
||||
static inline void mga_dma_dispatch_tex_blit( drm_device_t *dev,
|
||||
unsigned long bus_address,
|
||||
int length,
|
||||
unsigned int destOrg )
|
||||
{
|
||||
drm_mga_private_t *dev_priv = dev->dev_private;
|
||||
int use_agp = PDEA_pagpxfer_enable;
|
||||
u16 y2;
|
||||
PRIMLOCALS;
|
||||
|
||||
length = length / sizeof(u32);
|
||||
y2 = length / 64;
|
||||
|
||||
PRIM_OVERFLOW(dev, dev_priv, 30);
|
||||
PRIMGETPTR( dev_priv );
|
||||
|
||||
dev_priv->last_sync_tag = mga_create_sync_tag(dev);
|
||||
|
||||
PRIMOUTREG( MGAREG_DSTORG, destOrg);
|
||||
PRIMOUTREG( MGAREG_MACCESS, 0x00000002);
|
||||
PRIMOUTREG( MGAREG_SRCORG, bus_address | use_agp);
|
||||
PRIMOUTREG( MGAREG_AR5, 64);
|
||||
|
||||
PRIMOUTREG( MGAREG_PITCH, 64);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DWGCTL, MGA_COPY_CMD);
|
||||
|
||||
PRIMOUTREG(MGAREG_AR0, 63);
|
||||
PRIMOUTREG(MGAREG_AR3, 0);
|
||||
PRIMOUTREG(MGAREG_FXBNDRY, (63 << 16));
|
||||
PRIMOUTREG(MGAREG_YDSTLEN+MGAREG_MGA_EXEC, y2);
|
||||
|
||||
PRIMOUTREG( MGAREG_SRCORG, 0);
|
||||
PRIMOUTREG( MGAREG_PITCH, dev_priv->stride / dev_priv->cpp);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag);
|
||||
PRIMADVANCE(dev_priv);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void mga_dma_dispatch_vertex(drm_device_t *dev,
|
||||
drm_buf_t *buf, int real_idx,
|
||||
|
|
@ -502,8 +482,8 @@ static inline void mga_dma_dispatch_vertex(drm_device_t *dev,
|
|||
int length = buf->used;
|
||||
int use_agp = PDEA_pagpxfer_enable;
|
||||
int i = 0;
|
||||
PRIMLOCALS;
|
||||
int primary_needed;
|
||||
PRIMLOCALS;
|
||||
|
||||
DRM_DEBUG("dispatch vertex %d addr 0x%lx, length 0x%x nbox %d dirty %x\n",
|
||||
buf->idx, address, length, sarea_priv->nbox, sarea_priv->dirty);
|
||||
|
|
@ -592,7 +572,8 @@ static inline void mga_dma_dispatch_clear( drm_device_t *dev, int flags,
|
|||
unsigned int clear_zval )
|
||||
{
|
||||
drm_mga_private_t *dev_priv = dev->dev_private;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
unsigned int *regs = sarea_priv->ContextState;
|
||||
int nbox = sarea_priv->nbox;
|
||||
xf86drmClipRectRec *pbox = sarea_priv->boxes;
|
||||
unsigned int cmd;
|
||||
|
|
@ -604,9 +585,9 @@ static inline void mga_dma_dispatch_clear( drm_device_t *dev, int flags,
|
|||
cmd = MGA_CLEAR_CMD | DC_atype_blk;
|
||||
else
|
||||
cmd = MGA_CLEAR_CMD | DC_atype_rstr;
|
||||
|
||||
primary_needed = nbox * 35;
|
||||
if(primary_needed == 0) primary_needed = 35;
|
||||
|
||||
primary_needed = nbox * 60;
|
||||
if(primary_needed == 0) primary_needed = 60;
|
||||
PRIM_OVERFLOW(dev, dev_priv, primary_needed);
|
||||
PRIMGETPTR( dev_priv );
|
||||
dev_priv->last_sync_tag = mga_create_sync_tag(dev);
|
||||
|
|
@ -658,6 +639,12 @@ static inline void mga_dma_dispatch_clear( drm_device_t *dev, int flags,
|
|||
}
|
||||
}
|
||||
|
||||
/* Force reset of DWGCTL */
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
|
||||
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
|
|
@ -669,6 +656,7 @@ static inline void mga_dma_dispatch_swap( drm_device_t *dev )
|
|||
{
|
||||
drm_mga_private_t *dev_priv = dev->dev_private;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
unsigned int *regs = sarea_priv->ContextState;
|
||||
int nbox = sarea_priv->nbox;
|
||||
xf86drmClipRectRec *pbox = sarea_priv->boxes;
|
||||
int i;
|
||||
|
|
@ -676,7 +664,7 @@ static inline void mga_dma_dispatch_swap( drm_device_t *dev )
|
|||
PRIMLOCALS;
|
||||
|
||||
primary_needed = nbox * 5;
|
||||
primary_needed += 15;
|
||||
primary_needed += 60;
|
||||
PRIM_OVERFLOW(dev, dev_priv, primary_needed);
|
||||
PRIMGETPTR( dev_priv );
|
||||
|
||||
|
|
@ -705,6 +693,12 @@ static inline void mga_dma_dispatch_swap( drm_device_t *dev )
|
|||
PRIMOUTREG(MGAREG_FXBNDRY, pbox[i].x1|((pbox[i].x2 - 1)<<16));
|
||||
PRIMOUTREG(MGAREG_YDSTLEN+MGAREG_MGA_EXEC, (pbox[i].y1<<16)|h);
|
||||
}
|
||||
|
||||
/* Force reset of DWGCTL */
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
|
||||
|
||||
PRIMOUTREG( MGAREG_SRCORG, 0);
|
||||
PRIMOUTREG( MGAREG_DMAPAD, 0);
|
||||
|
|
@ -768,36 +762,45 @@ int mga_swap_bufs(struct inode *inode, struct file *filp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* This is very broken */
|
||||
int mga_iload(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_t *buf;
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
__volatile__ unsigned int *status =
|
||||
(__volatile__ unsigned int *)dev_priv->status_page;
|
||||
drm_mga_iload_t iload;
|
||||
|
||||
copy_from_user_ret(&iload, (drm_mga_iload_t *)arg, sizeof(iload),
|
||||
-EFAULT);
|
||||
buf = dma->buflist[iload.idx];
|
||||
#if 0
|
||||
sarea_priv->dirty |= (MGA_UPLOAD_CTX | MGA_UPLOAD_2D);
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
__volatile__ unsigned int *status =
|
||||
(__volatile__ unsigned int *)dev_priv->status_page;
|
||||
drm_buf_t *buf;
|
||||
drm_mga_buf_priv_t *buf_priv;
|
||||
drm_mga_iload_t iload;
|
||||
unsigned long bus_address;
|
||||
|
||||
DRM_DEBUG("buf->used : %d\n", buf->used);
|
||||
|
||||
mga_dma_dispatch_tex_blit(dev, buf, iload.x1, iload.x2, iload.y1, iload.y2,
|
||||
iload.destOrg, iload.mAccess, iload.pitch);
|
||||
copy_from_user_ret(&iload, (drm_mga_iload_t *)arg, sizeof(iload),
|
||||
-EFAULT);
|
||||
|
||||
buf = dma->buflist[ iload.idx ];
|
||||
buf_priv = buf->dev_private;
|
||||
bus_address = buf->bus_address;
|
||||
|
||||
if(mgaVerifyIload(dev_priv,
|
||||
iload.destOrg,
|
||||
bus_address,
|
||||
iload.length)) {
|
||||
mga_freelist_put(dev, buf);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sarea_priv->dirty |= MGA_UPLOAD_CTX;
|
||||
|
||||
mga_dma_dispatch_tex_blit(dev, bus_address, iload.length,
|
||||
iload.destOrg);
|
||||
buf_priv->my_freelist->age = dev_priv->last_sync_tag;
|
||||
mga_freelist_put(dev, buf);
|
||||
mga_dma_schedule(dev, 1);
|
||||
#endif
|
||||
mga_freelist_put(dev, buf);
|
||||
sarea_priv->last_dispatch = status[1];
|
||||
return 0;
|
||||
sarea_priv->last_dispatch = status[1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mga_vertex(struct inode *inode, struct file *filp,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue