diff options
author | Jeff Hartmann <jhartmann@valinux.com> | 2000-02-27 08:13:00 +0000 |
---|---|---|
committer | Jeff Hartmann <jhartmann@valinux.com> | 2000-02-27 08:13:00 +0000 |
commit | 2f2480f94ed93e2ad452c6bc22a1eb63e4f37ea5 (patch) | |
tree | 0e8ff88f5d4176bd0d7987e6f6ae98dc8d5d765e | |
parent | c69d96fc30b6a668d43d38ca8f27cfc5983ec621 (diff) |
Changed all printk to DRM_DEBUG + various cleanup and bugfixes
-rw-r--r-- | linux-core/i810_dma.c | 41 | ||||
-rw-r--r-- | linux-core/i810_drv.c | 110 | ||||
-rw-r--r-- | linux-core/mga_drv.c | 97 | ||||
-rw-r--r-- | linux/agpsupport.c | 7 | ||||
-rw-r--r-- | linux/ctxbitmap.c | 4 | ||||
-rw-r--r-- | linux/i810_bufs.c | 316 | ||||
-rw-r--r-- | linux/i810_context.c | 16 | ||||
-rw-r--r-- | linux/i810_dma.c | 41 | ||||
-rw-r--r-- | linux/i810_drv.c | 110 | ||||
-rw-r--r-- | linux/memory.c | 6 | ||||
-rw-r--r-- | linux/mga_context.c | 16 | ||||
-rw-r--r-- | linux/mga_dma.c | 307 | ||||
-rw-r--r-- | linux/mga_dma.h | 21 | ||||
-rw-r--r-- | linux/mga_drm_public.h | 11 | ||||
-rw-r--r-- | linux/mga_drv.c | 97 | ||||
-rw-r--r-- | linux/mga_state.c | 231 |
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, |