Changed all printk to DRM_DEBUG + various cleanup and bugfixes

This commit is contained in:
Jeff Hartmann 2000-02-27 08:13:00 +00:00
parent c69d96fc30
commit 2f2480f94e
16 changed files with 452 additions and 979 deletions

View file

@ -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);

View file

@ -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();

View file

@ -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);

View file

@ -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)))

View file

@ -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;

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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();

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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,