diff options
author | Jeff Hartmann <jhartmann@valinux.com> | 2000-01-27 23:48:40 +0000 |
---|---|---|
committer | Jeff Hartmann <jhartmann@valinux.com> | 2000-01-27 23:48:40 +0000 |
commit | 621f166c9d0127f94610e4c3a6a14b8176702a2a (patch) | |
tree | a2d239624796cb1c608661292baad1ccde4b721d | |
parent | 8663acd3b5f8f6515b388930a961f630d7f6ef57 (diff) |
Updates to get dma working + support for Xserver changes
-rw-r--r-- | linux-core/drmP.h | 2 | ||||
-rw-r--r-- | linux-core/mga_drv.c | 1 | ||||
-rw-r--r-- | linux/bufs.c | 4 | ||||
-rw-r--r-- | linux/dma.c | 2 | ||||
-rw-r--r-- | linux/drm.h | 1 | ||||
-rw-r--r-- | linux/drmP.h | 2 | ||||
-rw-r--r-- | linux/lists.c | 2 | ||||
-rw-r--r-- | linux/mga_bufs.c | 42 | ||||
-rw-r--r-- | linux/mga_dma.c | 333 | ||||
-rw-r--r-- | linux/mga_drm_public.h | 160 | ||||
-rw-r--r-- | linux/mga_drv.c | 1 | ||||
-rw-r--r-- | linux/mga_drv.h | 35 | ||||
-rw-r--r-- | linux/mga_state.c | 209 | ||||
-rw-r--r-- | shared-core/drm.h | 1 | ||||
-rw-r--r-- | shared/drm.h | 1 |
15 files changed, 693 insertions, 103 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 042de764..97d2539a 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -522,7 +522,7 @@ typedef struct drm_device { drm_agp_head_t *agp; #endif unsigned long *ctx_bitmap; - void *SAREAprivate; + void *dev_private; } drm_device_t; diff --git a/linux-core/mga_drv.c b/linux-core/mga_drv.c index d037b1b1..81c08e81 100644 --- a/linux-core/mga_drv.c +++ b/linux-core/mga_drv.c @@ -104,6 +104,7 @@ static drm_ioctl_desc_t mga_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 }, }; #define MGA_IOCTL_COUNT DRM_ARRAY_SIZE(mga_ioctls) diff --git a/linux/bufs.c b/linux/bufs.c index c016734c..7b0cd757 100644 --- a/linux/bufs.c +++ b/linux/bufs.c @@ -60,7 +60,7 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd, return -EFAULT; } - DRM_DEBUG("offset = 0x%08lx, size = 0x%08lx, type = %d\n", + DRM_INFO("offset = 0x%08lx, size = 0x%08lx, type = %d\n", map->offset, map->size, map->type); if ((map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK))) { drm_free(map, sizeof(*map), DRM_MEM_MAPS); @@ -111,6 +111,7 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd, return -EINVAL; } + printk("Past switch\n"); down(&dev->struct_sem); if (dev->maplist) { ++dev->map_count; @@ -135,6 +136,7 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd, sizeof(map->offset), -EFAULT); } + printk("AddMap succeeded\n"); return 0; } diff --git a/linux/dma.c b/linux/dma.c index 0d19792a..53e7941b 100644 --- a/linux/dma.c +++ b/linux/dma.c @@ -425,8 +425,10 @@ int drm_dma_enqueue(drm_device_t *dev, drm_dma_t *d) current->pid, buf->idx, buf->list); } buf->used = d->send_sizes[i]; +#if 0 buf->bus_address = dev->agp->base + 65536 + (idx * 524288); +#endif buf->while_locked = while_locked; buf->context = d->context; if (!buf->used) { diff --git a/linux/drm.h b/linux/drm.h index 17fe54fc..77d4efb8 100644 --- a/linux/drm.h +++ b/linux/drm.h @@ -327,4 +327,5 @@ typedef struct drm_agp_info { #define DRM_IOCTL_AGP_BIND DRM_IOWR(0x36, drm_agp_binding_t) #define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t) +/* 0x40 is reserved for mga dma init */ #endif diff --git a/linux/drmP.h b/linux/drmP.h index 042de764..97d2539a 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -522,7 +522,7 @@ typedef struct drm_device { drm_agp_head_t *agp; #endif unsigned long *ctx_bitmap; - void *SAREAprivate; + void *dev_private; } drm_device_t; diff --git a/linux/lists.c b/linux/lists.c index 6c9f9767..6917527b 100644 --- a/linux/lists.c +++ b/linux/lists.c @@ -154,7 +154,7 @@ int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf) buf->list = DRM_LIST_FREE; do { old = bl->next; - bl->next = old; + buf->next = old; prev = cmpxchg(&bl->next, old, buf); if (++count > DRM_LOOPING_LIMIT) { DRM_ERROR("Looping\n"); diff --git a/linux/mga_bufs.c b/linux/mga_bufs.c index cd608dd2..46219a31 100644 --- a/linux/mga_bufs.c +++ b/linux/mga_bufs.c @@ -32,6 +32,7 @@ #define __NO_VERSION__ #include "drmP.h" +#include "mga_drv.h" #include "linux/un.h" int mga_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, @@ -69,7 +70,7 @@ int mga_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; total = PAGE_SIZE << page_order; byte_count = 0; - +#if 0 printk("count: %d\n", count); printk("order: %d\n", order); printk("size: %d\n", size); @@ -78,7 +79,7 @@ int mga_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, printk("page_order: %d\n", page_order); printk("total: %d\n", total); printk("byte_count: %d\n", byte_count); - +#endif if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL; if (dev->queue_count) return -EBUSY; /* Not while in use */ spin_lock(&dev->count_lock); @@ -116,10 +117,12 @@ int mga_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, buf->total = alignment; buf->order = order; buf->used = 0; +#if 0 printk("offset : %d\n", offset); - buf->offset = agp_offset + offset; +#endif + buf->offset = offset; /* Hrm */ buf->bus_address = dev->agp->base + agp_offset + offset; - buf->address = agp_offset + offset + dev->agp->base; + buf->address = (void *)(agp_offset + offset + dev->agp->base); buf->next = NULL; buf->waiting = 0; buf->pending = 0; @@ -148,10 +151,13 @@ int mga_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]); @@ -168,7 +174,7 @@ int mga_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); @@ -177,9 +183,11 @@ int mga_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, 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; } @@ -541,28 +549,29 @@ int mga_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, (drm_buf_map_t *)arg, sizeof(request), -EFAULT); +#if 0 printk("mga_mapbufs\n"); printk("dma->flags : %lx\n", dma->flags); +#endif if (request.count >= dma->buf_count) { if(dma->flags & _DRM_DMA_USE_AGP) { - /* This is an ugly vicious hack */ + drm_mga_private_t *dev_priv = dev->dev_private; drm_map_t *map = NULL; - for(i = 0; i < dev->map_count; i++) { - map = dev->maplist[i]; - if(map->type == _DRM_AGP) break; - } - if (i >= dev->map_count || !map) { - printk("i : %d\n", i); + + 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 { @@ -613,7 +622,8 @@ int mga_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, &request, sizeof(request), -EFAULT); - +#if 0 printk("retcode : %d\n", retcode); +#endif return retcode; } diff --git a/linux/mga_dma.c b/linux/mga_dma.c index f6b237bd..2c4856ed 100644 --- a/linux/mga_dma.c +++ b/linux/mga_dma.c @@ -54,22 +54,37 @@ #define ADRINDEX0(r) (u8)((r - DWGREG0) >> 2) #define ADRINDEX1(r) (u8)(((r - DWGREG1) >> 2) | 0x80) #define ADRINDEX(r) (ISREG0(r) ? ADRINDEX0(r) : ADRINDEX1(r)) - -#define DMAOUTREG(reg, val) do { \ -buffer.tempIndex[buffer.outcount]=ADRINDEX(reg); \ -buffer.dma_ptr[1+buffer.outcount] = val; \ -if( ++buffer.outcount == 4) { \ -buffer.outcount = 0; \ -buffer.dma_ptr[0] = *(u32 *)buffer.tempIndex; \ -buffer.dma_ptr+=5; \ -buffer.num_dwords += 5; \ -} \ +#define DMALOCALS() u8 tempIndex[4]; u32 *dma_ptr; u32 phys_head; \ + int outcount, num_dwords; unsigned long flags + +#define DMAGETPTR() do { \ +dma_ptr = dev_priv->current_dma_ptr; \ +phys_head = dev_priv->prim_phys_head; \ +outcount = 0; \ +num_dwords = dev_priv->prim_num_dwords; \ +} while(0) + +#define DMAADVANCE() do { \ +dev_priv->prim_num_dwords = num_dwords; \ +dev_priv->current_dma_ptr = dma_ptr; \ +} while(0); + +#define DMAOUTREG(reg, val) do { \ +tempIndex[outcount]=ADRINDEX(reg); \ +dma_ptr[1+outcount] = val; \ +if( ++outcount == 4) { \ +outcount = 0; \ +dma_ptr[0] = *(u32 *)tempIndex; \ +dma_ptr+=5; \ +num_dwords += 5; \ +} \ }while (0) -#define CHECK_OVERFLOW(length) do { \ -if((buffer.max_dwords - buffer.num_dwords) < length) { \ - mga_prim_overflow(dev); \ -} \ +#define CHECK_OVERFLOW(length) do { \ +if((dev_priv->prim_max_dwords - dev_priv->prim_num_dwords) < \ + length) { \ + mga_prim_overflow(dev); \ +} \ }while(0) #define PDEA_pagpxfer_enable 0x2 @@ -78,17 +93,6 @@ if((buffer.max_dwords - buffer.num_dwords) < length) { \ #define MGA_FXBNDRY(x1,x2) DMAOUTREG(MGAREG_FXBNDRY,((x2) << 16) | (x1)) #define MGA_DWGCTL_EXEC(x) DMAOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC,x) -typedef struct _mga_primary_buffer { - u32 *head; - u32 *dma_ptr; - u8 tempIndex[4]; - int outcount; - int num_dwords; - int max_dwords; - unsigned long phys_head; -} mgaPrimBuf; - -static mgaPrimBuf buffer; typedef enum { TT_GENERAL, TT_BLIT, @@ -96,12 +100,14 @@ typedef enum { TT_VERTEX } transferType_t; +/* MUST BE CALLED WITH DISPATCH LOCK HELD */ static inline void mga_prim_overflow(drm_device_t *dev) { - buffer.num_dwords = 0; - buffer.outcount = 0; - buffer.dma_ptr = buffer.head; - MGA_WRITE(MGAREG_PRIMADDRESS, buffer.phys_head | TT_GENERAL); + drm_mga_private_t *dev_private_ptr = dev->dev_private; + + dev_private_ptr->prim_num_dwords = 0; + dev_private_ptr->current_dma_ptr = dev_private_ptr->prim_head; + MGA_WRITE(MGAREG_PRIMADDRESS, dev_private_ptr->prim_phys_head | TT_GENERAL); } static void mga_delay(void) @@ -109,19 +115,98 @@ static void mga_delay(void) return; } -void mga_dma_init(drm_device_t *dev) +int mga_dma_cleanup(drm_device_t *dev) { - int i; + if(dev->dev_private) { + drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; + int temp; + + if(dev_priv->ioremap) { + temp = dev_priv->warp_mc_size + dev_priv->primary_size; + temp = ((temp + PAGE_SIZE - 1) / + PAGE_SIZE) * PAGE_SIZE; + drm_ioremapfree((void *) dev_priv->ioremap, temp); + } + drm_free(dev->dev_private, sizeof(drm_mga_private_t), DRM_MEM_DRIVER); + dev->dev_private = NULL; + } + return 0; +} - memset(&buffer, 0, sizeof(mgaPrimBuf)); - buffer.phys_head = dev->agp->agp_info.aper_base; - buffer.head = (u32 *) drm_ioremap(buffer.phys_head, 65536); - buffer.max_dwords = 16383; - mga_prim_overflow(dev); - DMAOUTREG(MGAREG_DMAPAD, 0); +static int mga_dma_initialize(drm_device_t *dev, drm_mga_private_t *dev_priv, + drm_mga_init_t *init) { + drm_map_t *prim_map = NULL; + drm_map_t *sarea_map = NULL; + int temp; + + dev->dev_private = (void *) dev_priv; + printk("dev_private\n"); + memset(dev_priv, 0, sizeof(drm_mga_private_t)); + if((init->reserved_map_idx >= dev->map_count) || + (init->buffer_map_idx >= dev->map_count)) { + mga_dma_cleanup(dev); + printk("reserved_map or buffer_map are invalid\n"); + return -EINVAL; + } + + dev_priv->reserved_map_idx = init->reserved_map_idx; + dev_priv->buffer_map_idx = init->buffer_map_idx; + sarea_map = dev->maplist[0]; + dev_priv->sarea_priv = (drm_mga_sarea_t *) + ((u8 *)sarea_map->handle + + init->sarea_priv_offset); + printk("sarea_priv\n"); + + /* Scale primary size to the next page */ + dev_priv->primary_size = ((init->primary_size + PAGE_SIZE - 1) / + PAGE_SIZE) * PAGE_SIZE; + dev_priv->warp_mc_size = init->warp_mc_size; + dev_priv->type = init->type; + dev_priv->fbOffset = init->fbOffset; + dev_priv->backOffset = init->backOffset; + dev_priv->depthOffset = init->depthOffset; + dev_priv->textureOffset = init->textureOffset; + dev_priv->textureSize = init->textureSize; + dev_priv->cpp = init->cpp; + dev_priv->sgram = init->sgram; + dev_priv->stride = init->stride; + + printk("memcpy\n"); + memcpy(&dev_priv->WarpIndex, &init->WarpIndex, + sizeof(mgaWarpIndex) * MGA_MAX_WARP_PIPES); + printk("memcpy done\n"); + prim_map = dev->maplist[init->reserved_map_idx]; + dev_priv->prim_phys_head = dev->agp->base + init->reserved_map_agpstart; + temp = init->warp_mc_size + dev_priv->primary_size; + temp = ((temp + PAGE_SIZE - 1) / + PAGE_SIZE) * PAGE_SIZE; + printk("temp : %x\n", temp); + printk("dev->agp->base: %lx\n", dev->agp->base); + printk("init->reserved_map_agpstart: %lx\n", init->reserved_map_agpstart); + dev_priv->ioremap = drm_ioremap(dev->agp->base + init->reserved_map_agpstart, + temp); + if(dev_priv->ioremap == NULL) { + printk("Ioremap failed\n"); + mga_dma_cleanup(dev); + return -ENOMEM; + } + dev_priv->prim_head = (u32 *)dev_priv->ioremap; + printk("dev_priv->prim_head : %lx\n", dev_priv->prim_head); + dev_priv->current_dma_ptr = dev_priv->prim_head; + dev_priv->prim_num_dwords = 0; + dev_priv->prim_max_dwords = dev_priv->primary_size / sizeof(unsigned long); + + printk("dma initialization\n"); + /* Private is now filled in, initialize the hardware */ + { + DMALOCALS(); + mga_prim_overflow(dev); + DMAGETPTR(); + DMAOUTREG(MGAREG_DMAPAD, 0); DMAOUTREG(MGAREG_DMAPAD, 0); DMAOUTREG(MGAREG_DWGSYNC, 0); DMAOUTREG(MGAREG_SOFTRAP, 0); + DMAADVANCE(); /* Poll for the first buffer to insure that * the status register will be correct @@ -129,32 +214,62 @@ void mga_dma_init(drm_device_t *dev) MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG); while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) { + int i; for(i = 0 ; i < 4096; i++) mga_delay(); } - MGA_WRITE(MGAREG_PRIMEND, (buffer.phys_head + - (buffer.num_dwords*sizeof(unsigned long))) | + MGA_WRITE(MGAREG_PRIMEND, (phys_head + + (num_dwords*sizeof(unsigned long))) | PDEA_pagpxfer_enable); while(MGA_READ(MGAREG_DWGSYNC) == MGA_SYNC_TAG) { + int i; for(i = 0; i < 4096; i++) mga_delay(); } + + } + + printk("dma init was successful\n"); + return 0; } -void mga_dma_cleanup(drm_device_t *dev) +int mga_dma_init(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { - if(buffer.head != NULL) - drm_ioremapfree((void *)buffer.head, 65536); + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_mga_private_t *dev_priv; + drm_mga_init_t init; + int retcode = 0; + + copy_from_user_ret(&init, (drm_mga_init_t *)arg, sizeof(init), -EFAULT); + + switch(init.func) { + case MGA_INIT_DMA: + dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER); + if(dev_priv == NULL) return -ENOMEM; + retcode = mga_dma_initialize(dev, dev_priv, &init); + break; + case MGA_CLEANUP_DMA: + retcode = mga_dma_cleanup(dev); + break; + default: + retcode = -EINVAL; + break; + } + return retcode; } static void mga_dma_dispatch(drm_device_t *dev, unsigned long address, unsigned long length) { + drm_mga_private_t *dev_priv = dev->dev_private; int use_agp = PDEA_pagpxfer_enable; static int j = 0; static int k = 0; int cmd; + DMALOCALS(); CHECK_OVERFLOW(20); - + DMAGETPTR(); cmd = DC_opcod_iload | /* image load */ DC_atype_rpl | /* raster replace mode */ DC_linear_linear | /* linear source */ @@ -179,63 +294,113 @@ static void mga_dma_dispatch(drm_device_t *dev, unsigned long address, DMAOUTREG(MGAREG_SECEND, (address + length) | use_agp); DMAOUTREG(MGAREG_DMAPAD, 0); DMAOUTREG(MGAREG_DMAPAD, 0); - DMAOUTREG(MGAREG_DMAPAD, 0); + DMAOUTREG(MGAREG_DWGSYNC, 0); DMAOUTREG(MGAREG_SOFTRAP, 0); + DMAADVANCE(); + + MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG); + while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) ; - MGA_WRITE(MGAREG_PRIMEND, (buffer.phys_head + - (buffer.num_dwords*sizeof(unsigned long))) | + MGA_WRITE(MGAREG_PRIMEND, (phys_head + + (num_dwords*sizeof(unsigned long))) | use_agp); + k += 20; j += 5; if( j < 1280-512) j = 0; if( k < 512) k = 0; } +/* Frees dispatch lock */ static inline void mga_dma_quiescent(drm_device_t *dev) { - while((MGA_READ(MGAREG_STATUS) & 0x00020000) == 0) ; + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + + while(1) { + atomic_inc(&dev_priv->dispatch_lock); + if(atomic_read(&dev_priv->dispatch_lock) == 1) { + break; + } else { + atomic_dec(&dev_priv->dispatch_lock); + } + } + while((MGA_READ(MGAREG_STATUS) & 0x00020001) != 0x00020000) ; MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG); while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) ; + atomic_dec(&dev_priv->dispatch_lock); } static inline void mga_dma_ready(drm_device_t *dev) { - while((MGA_READ(MGAREG_STATUS) & 0x00020000) == 0) ; + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + + while(1) { + atomic_inc(&dev_priv->dispatch_lock); + if(atomic_read(&dev_priv->dispatch_lock) == 1) { + atomic_dec(&dev_priv->dispatch_lock); + break; + } else { + atomic_dec(&dev_priv->dispatch_lock); + } + } } +/* Keeps dispatch lock held */ + static inline int mga_dma_is_ready(drm_device_t *dev) { - if((MGA_READ(MGAREG_STATUS) & 0x00020000) == 0) - return 0; - else - return 1; + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + + atomic_inc(&dev_priv->dispatch_lock); + if(atomic_read(&dev_priv->dispatch_lock) == 1) { + /* We got the lock */ + return 1; + } else { + atomic_dec(&dev_priv->dispatch_lock); + return 0; + } +} + +static inline int mga_dma_is_ready_no_hold(drm_device_t *dev) +{ + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + + atomic_inc(&dev_priv->dispatch_lock); + if(atomic_read(&dev_priv->dispatch_lock) == 1) { + /* We got the lock, but free it */ + atomic_dec(&dev_priv->dispatch_lock); + return 1; + } else { + atomic_dec(&dev_priv->dispatch_lock); + return 0; + } } static void mga_dma_service(int irq, void *device, struct pt_regs *regs) { drm_device_t *dev = (drm_device_t *)device; drm_device_dma_t *dma = dev->dma; - + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + + atomic_dec(&dev_priv->dispatch_lock); atomic_inc(&dev->total_irq); + MGA_WRITE(MGAREG_ICLEAR, 0xfa7); - if (mga_dma_is_ready(dev)) { /* Free previous buffer */ - if (test_and_set_bit(0, &dev->dma_flag)) { - atomic_inc(&dma->total_missed_free); - return; - } - if (dma->this_buffer) { - drm_free_buffer(dev, dma->this_buffer); - dma->this_buffer = NULL; - } - clear_bit(0, &dev->dma_flag); + if (test_and_set_bit(0, &dev->dma_flag)) { + atomic_inc(&dma->total_missed_free); + return; + } + if (dma->this_buffer) { + drm_free_buffer(dev, dma->this_buffer); + dma->this_buffer = NULL; + } + clear_bit(0, &dev->dma_flag); /* Dispatch new buffer */ - queue_task(&dev->tq, &tq_immediate); - mark_bh(IMMEDIATE_BH); - } + queue_task(&dev->tq, &tq_immediate); + mark_bh(IMMEDIATE_BH); - MGA_WRITE(MGAREG_ICLEAR, 0xfa7); } /* Only called by mga_dma_schedule. */ @@ -250,6 +415,8 @@ static int mga_do_dma(drm_device_t *dev, int locked) #if DRM_DMA_HISTOGRAM cycles_t dma_start, dma_stop; #endif + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + if (test_and_set_bit(0, &dev->dma_flag)) { atomic_inc(&dma->total_missed_dma); return -EBUSY; @@ -288,11 +455,11 @@ static int mga_do_dma(drm_device_t *dev, int locked) return 0; } - if (!mga_dma_is_ready(dev)) { + if (mga_dma_is_ready(dev) == 0) { clear_bit(0, &dev->dma_flag); return -EBUSY; } - + if (buf->while_locked) { if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { DRM_ERROR("Dispatching buffer %d from pid %d" @@ -304,6 +471,7 @@ static int mga_do_dma(drm_device_t *dev, int locked) DRM_KERNEL_CONTEXT)) { atomic_inc(&dma->total_missed_lock); clear_bit(0, &dev->dma_flag); + atomic_dec(&dev_priv->dispatch_lock); return -EBUSY; } } @@ -317,6 +485,7 @@ static int mga_do_dma(drm_device_t *dev, int locked) drm_free_buffer(dev, buf); } retcode = -EBUSY; + atomic_dec(&dev_priv->dispatch_lock); goto cleanup; /* POST: we will wait for the context @@ -355,7 +524,9 @@ cleanup: dma_stop = get_cycles(); atomic_inc(&dev->histo.dma[drm_histogram_slot(dma_stop - dma_start)]); #endif - + /* We hold the dispatch lock until the interrupt handler + * frees it + */ return retcode; } @@ -435,9 +606,9 @@ again: if (--expire) { if (missed != atomic_read(&dma->total_missed_sched)) { atomic_inc(&dma->total_lost); - if (mga_dma_is_ready(dev)) goto again; + if (mga_dma_is_ready_no_hold(dev)) goto again; } - if (processed && mga_dma_is_ready(dev)) { + if (processed && mga_dma_is_ready_no_hold(dev)) { atomic_inc(&dma->total_lost); processed = 0; goto again; @@ -587,7 +758,7 @@ static int mga_dma_priority(drm_device_t *dev, drm_dma_t *d) buf->time_queued = get_cycles(); buf->time_dispatched = buf->time_queued; #endif - address = dev->agp->base + 65536 + (idx * 524288); + address = buf->bus_address; #if 0 if (drm_lock_free(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) { @@ -710,15 +881,10 @@ int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd, } if (d.send_count) { -#if 1 if (d.flags & _DRM_DMA_PRIORITY) retcode = mga_dma_priority(dev, &d); else retcode = mga_dma_send_buffers(dev, &d); -#endif -#if 0 - retcode = mga_dma_priority(dev, &d); -#endif } d.granted_count = 0; @@ -817,9 +983,6 @@ int mga_control(struct inode *inode, struct file *filp, unsigned int cmd, drm_control_t ctl; int retcode; -#if 1 - mga_dma_init(dev); -#endif copy_from_user_ret(&ctl, (drm_control_t *)arg, sizeof(ctl), -EFAULT); switch (ctl.func) { @@ -915,10 +1078,14 @@ int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd, drm_flush_unblock(dev, lock.context, lock.flags); /* cleanup phase */ if (!ret) { - if (lock.flags & _DRM_LOCK_READY) + if (lock.flags & _DRM_LOCK_READY) { + printk("_DRM_LOCK_READY\n"); mga_dma_ready(dev); - if (lock.flags & _DRM_LOCK_QUIESCENT) + } + if (lock.flags & _DRM_LOCK_QUIESCENT) { + printk("_DRM_LOCK_QUIESCENT\n"); mga_dma_quiescent(dev); + } } printk("%d %s\n", lock.context, ret ? "interrupted" : "has lock"); diff --git a/linux/mga_drm_public.h b/linux/mga_drm_public.h new file mode 100644 index 00000000..8c066dd6 --- /dev/null +++ b/linux/mga_drm_public.h @@ -0,0 +1,160 @@ +/* mga_drm_public.h -- Public header for the Matrox g200/g400 driver -*- linux-c -*- + * Created: Tue Jan 25 01:50:01 1999 by jhartmann@precisioninsight.com + * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Author: Jeff Hartmann <jhartmann@precisioninsight.com> + * + * $XFree86$ + */ + +#ifndef _MGA_DRM_PUBLIC_H_ +#define _MGA_DRM_PUBLIC_H_ + +/* These defines must match the Xserver code */ +#define MGA_WARP_TGZ 0 +#define MGA_WARP_TGZA 1 +#define MGA_WARP_TGZAF 2 +#define MGA_WARP_TGZF 3 +#define MGA_WARP_TGZS 4 +#define MGA_WARP_TGZSA 5 +#define MGA_WARP_TGZSAF 6 +#define MGA_WARP_TGZSF 7 +#define MGA_WARP_T2GZ 8 +#define MGA_WARP_T2GZA 9 +#define MGA_WARP_T2GZAF 10 +#define MGA_WARP_T2GZF 11 +#define MGA_WARP_T2GZS 12 +#define MGA_WARP_T2GZSA 13 +#define MGA_WARP_T2GZSAF 14 +#define MGA_WARP_T2GZSF 15 + +#define MGA_MAX_WARP_PIPES 16 + +#define MGA_CARD_TYPE_G200 1 +#define MGA_CARD_TYPE_G400 2 + +/* Bogus values */ + +#define MGA_X_SETUP_SIZE 16 +#define MGA_SETUP_SIZE 16 +#define MGA_TEX_SETUP_SIZE 16 + +typedef struct _drm_mga_warp_index { + int installed; + unsigned long phys_addr; + int size; +} mgaWarpIndex; + +typedef struct drm_mga_init { + enum { + MGA_INIT_DMA = 0x01, + MGA_CLEANUP_DMA = 0x02 + } func; + int reserved_map_agpstart; + int reserved_map_idx; + int buffer_map_idx; + int sarea_priv_offset; + int primary_size; + int warp_mc_size; + int type; + int fbOffset; + int backOffset; + int depthOffset; + int textureOffset; + int textureSize; + int cpp; + int stride; + int sgram; + mgaWarpIndex WarpIndex[MGA_MAX_WARP_PIPES]; +} drm_mga_init_t; + +typedef struct _xf86drmClipRectRec { + unsigned short x1; + unsigned short y1; + unsigned short x2; + unsigned short y2; +} xf86drmClipRectRec; + +#define _MGA_2D_DIRTY 0 +/* These aren't finals, its just what the Xserver uses */ +#define _MGA_SETUP_PITCH 0 +#define _MGA_SETUP_CXBNDRY 1 +#define _MGA_SETUP_YTOP 2 +#define _MGA_SETUP_YBOT 3 +#define _MGA_SETUP_DSTORG 4 +#define _MGA_SETUP_MACCESS 5 +#define _MGA_SETUP_PLNWT 6 +#define _MGA_SETUP_ZORG 7 +#define _MGA_SETUP_YDSTLEN 8 +#define _MGA_SETUP_YDSTORG 9 +#define _MGA_SETUP_FXBNDRY 10 +#define _MGA_SETUP_SRCORG 11 +#define _MGA_SETUP_DSTORG 12 +#define _MGA_SETUP_SGN 13 +#define _MGA_SETUP_AR0 14 +#define _MGA_SETUP_AR1 15 +#define _MGA_SETUP_AR2 16 +#define _MGA_SETUP_AR3 17 +#define _MGA_SETUP_AR4 18 +#define _MGA_SETUP_AR5 19 +#define _MGA_SETUP_AR6 20 +#define _MGA_SETUP_CXRIGHT 21 +#define _MGA_SETUP_DWGCTL 22 +#define _MGA_SETUP_XYEND 23 +#define _MGA_SETUP_XYSTRT 24 +#define _MGA_SETUP_FCOL 25 +#define _MGA_SETUP_BCOL 26 +#define _MGA_SETUP_PAT0 27 +#define _MGA_SETUP_PAT1 28 +#define _MGA_SETUP_SHIFT 29 +#define _MGA_SETUP_SRC0 30 +#define _MGA_SETUP_SRC1 31 +#define _MGA_SETUP_SRC2 32 +#define _MGA_SETUP_SRC3 33 +#define _MGA_SETUP_OPMODE 34 +#define _MGA_SETUP_WIADDR2 35 +#define _MGA_SETUP_WGETMSB 36 +#define _MGA_SETUP_WVRTXSZ 37 +#define _MGA_SETUP_WACCEPTSEQ 38 +#define _MGA_SETUP_WIADDR 39 +#define _MGA_SETUP_WMISC 40 + + + +typedef struct _drm_mga_sarea { + int CtxOwner; + int TexOwner; + unsigned long ServerState[MGA_X_SETUP_SIZE]; + unsigned long ContextState[MGA_SETUP_SIZE]; + unsigned long Tex0State[MGA_TEX_SETUP_SIZE]; + unsigned long Tex1State[MGA_TEX_SETUP_SIZE]; + int WarpPipe; + unsigned long NewState; + int nbox; + xf86drmClipRectRec boxes[256]; +} drm_mga_sarea_t; + +#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) + +#endif diff --git a/linux/mga_drv.c b/linux/mga_drv.c index d037b1b1..81c08e81 100644 --- a/linux/mga_drv.c +++ b/linux/mga_drv.c @@ -104,6 +104,7 @@ static drm_ioctl_desc_t mga_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 }, }; #define MGA_IOCTL_COUNT DRM_ARRAY_SIZE(mga_ioctls) diff --git a/linux/mga_drv.h b/linux/mga_drv.h index f29fa5e2..5cf61883 100644 --- a/linux/mga_drv.h +++ b/linux/mga_drv.h @@ -31,6 +31,33 @@ #ifndef _MGA_DRV_H_ #define _MGA_DRV_H_ +#include "mga_drm_public.h" + +typedef struct _drm_mga_private { + int reserved_map_idx; + int buffer_map_idx; + drm_mga_sarea_t *sarea_priv; + int primary_size; + int warp_mc_size; + int type; + int fbOffset; + int backOffset; + int depthOffset; + int textureOffset; + int textureSize; + int cpp; + int stride; + int sgram; + mgaWarpIndex WarpIndex[MGA_MAX_WARP_PIPES]; + __volatile__ unsigned long softrap_age; + atomic_t dispatch_lock; + void *ioremap; + u32 *prim_head; + u32 *current_dma_ptr; + u32 prim_phys_head; + int prim_num_dwords; + int prim_max_dwords; +} drm_mga_private_t; /* mga_drv.c */ extern int mga_init(void); @@ -54,9 +81,17 @@ extern int mga_control(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +#if 0 extern void mga_dma_init(drm_device_t *dev); extern void mga_dma_cleanup(drm_device_t *dev); +#endif +extern int mga_dma_init(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int mga_dma_cleanup(drm_device_t *dev); + +/* mga_dma_init does init and release */ + /* mga_bufs.c */ extern int mga_addbufs(struct inode *inode, struct file *filp, diff --git a/linux/mga_state.c b/linux/mga_state.c new file mode 100644 index 00000000..1a1ed4fc --- /dev/null +++ b/linux/mga_state.c @@ -0,0 +1,209 @@ +/* mga_state.c -- State support for mga g200/g400 -*- linux-c -*- + * Created: Thu Jan 27 02:53:43 2000 by jhartmann@precisioninsight.com + * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: Jeff Hartmann <jhartmann@precisioninsight.com> + * Keith Whitwell <keithw@precisioninsight.com> + * + * $XFree86$ + * + */ + +#define __NO_VERSION__ +#include "drmP.h" +#include "mga_drv.h" +#include "mgareg_flags.h" + +void mga2drefresh(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; + +} + +void mgaContextRefresh(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; + +} + +void mgaTex0Refresh(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; + +} + +void mgaTex1Refresh(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; + +} + +/* WIADDR might not work in sec bufs, might need to use + * the primary buffer + */ +int mgaG400SwitchPipe(drm_device_t *dev, void *code) +{ + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_device_dma_t *dma = dev->dma; + drm_dma_t d; + drm_buf_t *buf; + float fParam = 12800.0f; + DMALOCALS(); + + buf = drm_freelist_get(&dma->bufs[order].freelist,_DRM_DMA_WAIT); + + /* This needs to get a buffer to fill */ + + DMAGETPTR(buf); + DMAOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend); + + if (sarea_priv->WarpPipe >= 8) { + DMAOUTREG(MGAREG_WVRTXSZ, 0x00001e09); + DMAOUTREG(MGAREG_WACCEPTSEQ, 0x1e000000); + } else { + DMAOUTREG(MGAREG_WVRTXSZ, 0x00001807); + DMAOUTREG(MGAREG_WACCEPTSEQ, 0x18000000); + } + + DMAOUTREG(MGAREG_WFLAG, 0); + DMAOUTREG(MGAREG_WFLAG1, 0); + + DMAOUTREG(0x2d00 + 56*4, *((mgaUI32 *)(&fParam))); + DMAOUTREG(MGAREG_DMAPAD, 0); + DMAOUTREG(MGAREG_DMAPAD, 0); + + /* Perhaps only the registers for the Tex Stage 1 should + * be set on the microcode that does multitex, however it + * makes no difference :( + */ + DMAOUTREG(0x2d00 + 49*4, 0); /* Tex stage 0 */ + DMAOUTREG(0x2d00 + 57*4, 0); /* Tex stage 0 */ + DMAOUTREG(0x2d00 + 53*4, 0); /* Tex stage 1 */ + DMAOUTREG(0x2d00 + 61*4, 0); /* Tex stage 1 */ + + DMAOUTREG(0x2d00 + 54*4, 0x40); /* Tex stage 0 : w */ + DMAOUTREG(0x2d00 + 62*4, 0x40); /* Tex stage 0 : h */ + DMAOUTREG(0x2d00 + 52*4, 0x40); /* Tex stage 1 : w */ + DMAOUTREG(0x2d00 + 60*4, 0x40); /* Tex stage 1 : h */ + + /* Attention! dma pading required due to hw bug (see specs) */ + DMAOUTREG(MGAREG_DMAPAD, 0xffffffff); + DMAOUTREG(MGAREG_DMAPAD, 0xffffffff); + DMAOUTREG(MGAREG_DMAPAD, 0xffffffff); + DMAOUTREG(MGAREG_WIADDR2,(unsigned long)(code) | WIA_wmode_start | + WIA_wagp_agp); + DMAADVANCE(buf); + d.context = DRM_KERNEL_CONTEXT; + d.send_count = 1; + d.send_indices = &buf->idx; + d.send_sizes = &buf->used; + d.flags = _DRM_DMA_GENERAL; + d.request_count = 0; + d.request_size = 0; + d.request_indices = NULL; + d.request_sizes = NULL; + d.granted_count = 0; + drm_dma_enqueue(dev, &d); + return 0; +} + +int mgaG200SwitchPipe(drm_device_t *dev, void *code) +{ + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_dma_t d; + drm_buf_t *buf; + DMALOCALS; + + /* This needs to get a buffer to fill */ + buf = drm_freelist_get(&dma->bufs[order].freelist,_DRM_DMA_WAIT); + + DMAGETPTR(buf); + DMAOUTREG(MGAREG_WIADDR, WIA_wmode_suspend); + DMAOUTREG(MGAREG_WVRTXSZ, 7); + DMAOUTREG(MGAREG_WFLAG, 0); + DMAOUTREG(0x2d00 + 24*4, 0); // tex w/h + + DMAOUTREG(0x2d00 + 25*4, 0x100); + DMAOUTREG(0x2d00 + 34*4, 0); // tex w/h + DMAOUTREG(0x2d00 + 42*4, 0xFFFF); + DMAOUTREG(0x2d00 + 60*4, 0xFFFF); + + /* Attention! dma pading required due to hw bug (see specs) */ + DMAOUTREG(MGAREG_DMAPAD, 0xffffffff); + DMAOUTREG(MGAREG_DMAPAD, 0xffffffff); + DMAOUTREG(MGAREG_DMAPAD, 0xffffffff); + DMAOUTREG(MGAREG_WIADDR,(unsigned long)(code) | WIA_wmode_start | + WIA_wagp_agp); + DMAADVANCE(buf); + d.context = DRM_KERNEL_CONTEXT; + d.send_count = 1; + d.send_indices = &buf->idx; + d.send_sizes = &buf->used; + d.flags = _DRM_DMA_GENERAL; + d.request_count = 0; + d.request_size = 0; + d.request_indices = NULL; + d.request_sizes = NULL; + d.granted_count = 0; + drm_dma_enqueue(dev, &d); + return 0; +} + +void mgaWarpPipeRefresh(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; + void *code; + int failure; + + code = (void *)dev_priv->WarpIndex[sarea_priv->WarpPipe].phys_addr; + + if(!code) { + printk("Invalid warp code selected : %d\n", sarea_priv->WarpPipe); + code = (void *)dev_priv->WarpIndex[0].phys_addr; + + if(!code) { + DRM_ERROR("No Warp Pipes Loaded\n"); + return; + } + } + switch(dev_priv->type) { + case MGA_CARD_TYPE_G400: + failure = mgaG400SwitchPipe(dev, code); + break; + case MGA_CARD_TYPE_G200: + failure = mgaG200SwitchPipe(dev, code); + break; + } + if(failure) { + DRM_ERROR("Failed to switch warp pipes to : %d\n", + sarea_priv->WarpPipe); + } +} diff --git a/shared-core/drm.h b/shared-core/drm.h index 17fe54fc..77d4efb8 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -327,4 +327,5 @@ typedef struct drm_agp_info { #define DRM_IOCTL_AGP_BIND DRM_IOWR(0x36, drm_agp_binding_t) #define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t) +/* 0x40 is reserved for mga dma init */ #endif diff --git a/shared/drm.h b/shared/drm.h index 17fe54fc..77d4efb8 100644 --- a/shared/drm.h +++ b/shared/drm.h @@ -327,4 +327,5 @@ typedef struct drm_agp_info { #define DRM_IOCTL_AGP_BIND DRM_IOWR(0x36, drm_agp_binding_t) #define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t) +/* 0x40 is reserved for mga dma init */ #endif |