summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Hartmann <jhartmann@valinux.com>2000-02-27 08:13:00 +0000
committerJeff Hartmann <jhartmann@valinux.com>2000-02-27 08:13:00 +0000
commit2f2480f94ed93e2ad452c6bc22a1eb63e4f37ea5 (patch)
tree0e8ff88f5d4176bd0d7987e6f6ae98dc8d5d765e
parentc69d96fc30b6a668d43d38ca8f27cfc5983ec621 (diff)
Changed all printk to DRM_DEBUG + various cleanup and bugfixes
-rw-r--r--linux-core/i810_dma.c41
-rw-r--r--linux-core/i810_drv.c110
-rw-r--r--linux-core/mga_drv.c97
-rw-r--r--linux/agpsupport.c7
-rw-r--r--linux/ctxbitmap.c4
-rw-r--r--linux/i810_bufs.c316
-rw-r--r--linux/i810_context.c16
-rw-r--r--linux/i810_dma.c41
-rw-r--r--linux/i810_drv.c110
-rw-r--r--linux/memory.c6
-rw-r--r--linux/mga_context.c16
-rw-r--r--linux/mga_dma.c307
-rw-r--r--linux/mga_dma.h21
-rw-r--r--linux/mga_drm_public.h11
-rw-r--r--linux/mga_drv.c97
-rw-r--r--linux/mga_state.c231
16 files changed, 452 insertions, 979 deletions
diff --git a/linux-core/i810_dma.c b/linux-core/i810_dma.c
index c374493a..25dfe3ce 100644
--- a/linux-core/i810_dma.c
+++ b/linux-core/i810_dma.c
@@ -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);
diff --git a/linux-core/i810_drv.c b/linux-core/i810_drv.c
index d98c16a8..179b8714 100644
--- a/linux-core/i810_drv.c
+++ b/linux-core/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();
diff --git a/linux-core/mga_drv.c b/linux-core/mga_drv.c
index d608d42e..48041354 100644
--- a/linux-core/mga_drv.c
+++ b/linux-core/mga_drv.c
@@ -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);
diff --git a/linux/agpsupport.c b/linux/agpsupport.c
index 4619560a..d60edc2e 100644
--- a/linux/agpsupport.c
+++ b/linux/agpsupport.c
@@ -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)))
diff --git a/linux/ctxbitmap.c b/linux/ctxbitmap.c
index f67209d4..c3e64a31 100644
--- a/linux/ctxbitmap.c
+++ b/linux/ctxbitmap.c
@@ -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;
diff --git a/linux/i810_bufs.c b/linux/i810_bufs.c
index ef250f1e..5c3adfad 100644
--- a/linux/i810_bufs.c
+++ b/linux/i810_bufs.c
@@ -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;
}
diff --git a/linux/i810_context.c b/linux/i810_context.c
index 6176b774..5503edf2 100644
--- a/linux/i810_context.c
+++ b/linux/i810_context.c
@@ -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);
}
diff --git a/linux/i810_dma.c b/linux/i810_dma.c
index c374493a..25dfe3ce 100644
--- a/linux/i810_dma.c
+++ b/linux/i810_dma.c
@@ -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);
diff --git a/linux/i810_drv.c b/linux/i810_drv.c
index d98c16a8..179b8714 100644
--- a/linux/i810_drv.c
+++ b/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();
diff --git a/linux/memory.c b/linux/memory.c
index 7bc7c79f..a02c7b4a 100644
--- a/linux/memory.c
+++ b/linux/memory.c
@@ -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;
}
}
diff --git a/linux/mga_context.c b/linux/mga_context.c
index 0e594477..2459b35b 100644
--- a/linux/mga_context.c
+++ b/linux/mga_context.c
@@ -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);
}
diff --git a/linux/mga_dma.c b/linux/mga_dma.c
index 79eaa693..8d1f1069 100644
--- a/linux/mga_dma.c
+++ b/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)
-{
- 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)
+static int __gettimeinmillis(void)
{
- 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, 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);
+ /* 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);
+
+ 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;
}
diff --git a/linux/mga_dma.h b/linux/mga_dma.h
index 000dc6b2..b5b73f99 100644
--- a/linux/mga_dma.h
+++ b/linux/mga_dma.h
@@ -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
diff --git a/linux/mga_drm_public.h b/linux/mga_drm_public.h
index fcc97db0..4e24853d 100644
--- a/linux/mga_drm_public.h
+++ b/linux/mga_drm_public.h
@@ -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
diff --git a/linux/mga_drv.c b/linux/mga_drv.c
index d608d42e..48041354 100644
--- a/linux/mga_drv.c
+++ b/linux/mga_drv.c
@@ -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);
diff --git a/linux/mga_state.c b/linux/mga_state.c
index 915e98a6..35545f02 100644
--- a/linux/mga_state.c
+++ b/linux/mga_state.c
@@ -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 );
+ if(length % 64) {
+ return -EINVAL;
+ }
+ return 0;
+}
- PRIMOUTREG(MGAREG_AR3, 0 );
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_SOFTRAP, 0);
- PRIMADVANCE(dev_priv);
+/* 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_DEBUG("buf->used : %d\n", buf->used);
+ 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;
- 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,