diff options
author | Alan Hourihane <alanh@fairlite.demon.co.uk> | 2001-03-02 14:10:06 +0000 |
---|---|---|
committer | Alan Hourihane <alanh@fairlite.demon.co.uk> | 2001-03-02 14:10:06 +0000 |
commit | 4254e50a7249bc14ed148b60ac06db3306862eaa (patch) | |
tree | 89fd8a4e27bc73f1d55dbac669ddf16221e5e9a2 | |
parent | 08a14259769b6291d2f62bdb2118a90f3896a9cf (diff) | |
download | drm-4254e50a7249bc14ed148b60ac06db3306862eaa.tar.gz |
Start work on gamma kernel driver to use AGP. Modify 2D driver to
initialize AGP buffers.
-rw-r--r-- | linux-core/drmP.h | 2 | ||||
-rw-r--r-- | linux/drm.h | 4 | ||||
-rw-r--r-- | linux/drmP.h | 2 | ||||
-rw-r--r-- | linux/gamma.h | 7 | ||||
-rw-r--r-- | linux/gamma_context.c | 319 | ||||
-rw-r--r-- | linux/gamma_dma.c | 239 | ||||
-rw-r--r-- | linux/gamma_drm.c | 33 | ||||
-rw-r--r-- | linux/gamma_drm.h | 48 | ||||
-rw-r--r-- | linux/gamma_drv.c | 4 | ||||
-rw-r--r-- | linux/gamma_drv.h | 8 | ||||
-rw-r--r-- | shared-core/drm.h | 4 | ||||
-rw-r--r-- | shared/drm.h | 4 |
12 files changed, 273 insertions, 401 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 4032689a..e15fabc8 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -300,7 +300,7 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, #if DRM_DEBUG_CODE #define DRM_DEBUG(fmt, arg...) \ do { \ - if ( DRM(flags) & DRM_FLAG_DEBUG ) \ + if (1 /* DRM(flags) & DRM_FLAG_DEBUG*/ ) \ printk(KERN_DEBUG \ "[" DRM_NAME ":" __FUNCTION__ "] " fmt , \ ##arg); \ diff --git a/linux/drm.h b/linux/drm.h index 40a85875..4aa0d672 100644 --- a/linux/drm.h +++ b/linux/drm.h @@ -85,6 +85,7 @@ typedef struct drm_tex_region { #include "i810_drm.h" #include "r128_drm.h" #include "radeon_drm.h" +#include "gamma_drm.h" #ifdef CONFIG_DRM_SIS #include "sis_drm.h" #endif @@ -443,6 +444,9 @@ typedef struct drm_agp_info { #define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t) #define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t) +/* GAMMA specific ioctls */ +#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t) + #ifdef CONFIG_DRM_SIS /* SiS specific ioctls */ #define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t) diff --git a/linux/drmP.h b/linux/drmP.h index 4032689a..e15fabc8 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -300,7 +300,7 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, #if DRM_DEBUG_CODE #define DRM_DEBUG(fmt, arg...) \ do { \ - if ( DRM(flags) & DRM_FLAG_DEBUG ) \ + if (1 /* DRM(flags) & DRM_FLAG_DEBUG*/ ) \ printk(KERN_DEBUG \ "[" DRM_NAME ":" __FUNCTION__ "] " fmt , \ ##arg); \ diff --git a/linux/gamma.h b/linux/gamma.h index 383c54af..1f184ef1 100644 --- a/linux/gamma.h +++ b/linux/gamma.h @@ -41,8 +41,10 @@ /* DMA customization: */ #define __HAVE_DMA 1 +#define __HAVE_AGP 1 +#define __MUST_HAVE_AGP 1 #define __HAVE_OLD_DMA 1 -#define __HAVE_PCI_DMA 1 +#define __HAVE_PCI_DMA 0 #define __HAVE_MULTIPLE_DMA_QUEUES 1 #define __HAVE_DMA_WAITQUEUE 1 @@ -84,4 +86,7 @@ GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 ); \ } while (0) +#define DRIVER_AGP_BUFFERS_MAP( dev ) \ + ((drm_gamma_private_t *)((dev)->dev_private))->buffers + #endif /* __GAMMA_H__ */ diff --git a/linux/gamma_context.c b/linux/gamma_context.c deleted file mode 100644 index d94054a2..00000000 --- a/linux/gamma_context.c +++ /dev/null @@ -1,319 +0,0 @@ -/* context.c -- IOCTLs for contexts and DMA queues -*- linux-c -*- - * Created: Tue Feb 2 08:37:54 1999 by faith@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * 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: - * Rickard E. (Rik) Faith <faith@valinux.com> - * - */ - -#define __NO_VERSION__ -#include "gamma.h" -#include "drmP.h" - -static int drm_init_queue(drm_device_t *dev, drm_queue_t *q, drm_ctx_t *ctx) -{ - DRM_DEBUG("\n"); - - if (atomic_read(&q->use_count) != 1 - || atomic_read(&q->finalization) - || atomic_read(&q->block_count)) { - DRM_ERROR("New queue is already in use: u%d f%d b%d\n", - atomic_read(&q->use_count), - atomic_read(&q->finalization), - atomic_read(&q->block_count)); - } - - atomic_set(&q->finalization, 0); - atomic_set(&q->block_count, 0); - atomic_set(&q->block_read, 0); - atomic_set(&q->block_write, 0); - atomic_set(&q->total_queued, 0); - atomic_set(&q->total_flushed, 0); - atomic_set(&q->total_locks, 0); - - init_waitqueue_head(&q->write_queue); - init_waitqueue_head(&q->read_queue); - init_waitqueue_head(&q->flush_queue); - - q->flags = ctx->flags; - - gamma_waitlist_create(&q->waitlist, dev->dma->buf_count); - - return 0; -} - - -/* drm_alloc_queue: -PRE: 1) dev->queuelist[0..dev->queue_count] is allocated and will not - disappear (so all deallocation must be done after IOCTLs are off) - 2) dev->queue_count < dev->queue_slots - 3) dev->queuelist[i].use_count == 0 and - dev->queuelist[i].finalization == 0 if i not in use -POST: 1) dev->queuelist[i].use_count == 1 - 2) dev->queue_count < dev->queue_slots */ - -static int drm_alloc_queue(drm_device_t *dev) -{ - int i; - drm_queue_t *queue; - int oldslots; - int newslots; - /* Check for a free queue */ - for (i = 0; i < dev->queue_count; i++) { - atomic_inc(&dev->queuelist[i]->use_count); - if (atomic_read(&dev->queuelist[i]->use_count) == 1 - && !atomic_read(&dev->queuelist[i]->finalization)) { - DRM_DEBUG("%d (free)\n", i); - return i; - } - atomic_dec(&dev->queuelist[i]->use_count); - } - /* Allocate a new queue */ - down(&dev->struct_sem); - - queue = gamma_alloc(sizeof(*queue), DRM_MEM_QUEUES); - memset(queue, 0, sizeof(*queue)); - atomic_set(&queue->use_count, 1); - - ++dev->queue_count; - if (dev->queue_count >= dev->queue_slots) { - oldslots = dev->queue_slots * sizeof(*dev->queuelist); - if (!dev->queue_slots) dev->queue_slots = 1; - dev->queue_slots *= 2; - newslots = dev->queue_slots * sizeof(*dev->queuelist); - - dev->queuelist = gamma_realloc(dev->queuelist, - oldslots, - newslots, - DRM_MEM_QUEUES); - if (!dev->queuelist) { - up(&dev->struct_sem); - DRM_DEBUG("out of memory\n"); - return -ENOMEM; - } - } - dev->queuelist[dev->queue_count-1] = queue; - - up(&dev->struct_sem); - DRM_DEBUG("%d (new)\n", dev->queue_count - 1); - return dev->queue_count - 1; -} - -int gamma_resctx(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -{ - drm_ctx_res_t res; - drm_ctx_t ctx; - int i; - - DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS); - if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res))) - return -EFAULT; - if (res.count >= DRM_RESERVED_CONTEXTS) { - memset(&ctx, 0, sizeof(ctx)); - for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { - ctx.handle = i; - if (copy_to_user(&res.contexts[i], - &i, - sizeof(i))) - return -EFAULT; - } - } - res.count = DRM_RESERVED_CONTEXTS; - if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res))) - return -EFAULT; - return 0; -} - - -int gamma_addctx(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_ctx_t ctx; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - if ((ctx.handle = drm_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) { - /* Init kernel's context and get a new one. */ - drm_init_queue(dev, dev->queuelist[ctx.handle], &ctx); - ctx.handle = drm_alloc_queue(dev); - } - drm_init_queue(dev, dev->queuelist[ctx.handle], &ctx); - DRM_DEBUG("%d\n", ctx.handle); - if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx))) - return -EFAULT; - return 0; -} - -int gamma_modctx(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_ctx_t ctx; - drm_queue_t *q; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - - DRM_DEBUG("%d\n", ctx.handle); - - if (ctx.handle < 0 || ctx.handle >= dev->queue_count) return -EINVAL; - q = dev->queuelist[ctx.handle]; - - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - /* No longer in use */ - atomic_dec(&q->use_count); - return -EINVAL; - } - - if (DRM_BUFCOUNT(&q->waitlist)) { - atomic_dec(&q->use_count); - return -EBUSY; - } - - q->flags = ctx.flags; - - atomic_dec(&q->use_count); - return 0; -} - -int gamma_getctx(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_ctx_t ctx; - drm_queue_t *q; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - - DRM_DEBUG("%d\n", ctx.handle); - - if (ctx.handle >= dev->queue_count) return -EINVAL; - q = dev->queuelist[ctx.handle]; - - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - /* No longer in use */ - atomic_dec(&q->use_count); - return -EINVAL; - } - - ctx.flags = q->flags; - atomic_dec(&q->use_count); - - if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx))) - return -EFAULT; - - return 0; -} - -int gamma_switchctx(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_ctx_t ctx; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - DRM_DEBUG("%d\n", ctx.handle); - return drm_context_switch(dev, dev->last_context, ctx.handle); -} - -int gamma_newctx(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_ctx_t ctx; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - DRM_DEBUG("%d\n", ctx.handle); - drm_context_switch_complete(dev, ctx.handle); - - return 0; -} - -int gamma_rmctx(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_ctx_t ctx; - drm_queue_t *q; - drm_buf_t *buf; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - DRM_DEBUG("%d\n", ctx.handle); - - if (ctx.handle >= dev->queue_count) return -EINVAL; - q = dev->queuelist[ctx.handle]; - - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - /* No longer in use */ - atomic_dec(&q->use_count); - return -EINVAL; - } - - atomic_inc(&q->finalization); /* Mark queue in finalization state */ - atomic_sub(2, &q->use_count); /* Mark queue as unused (pending - finalization) */ - - while (test_and_set_bit(0, &dev->interrupt_flag)) { - schedule(); - if (signal_pending(current)) { - clear_bit(0, &dev->interrupt_flag); - return -EINTR; - } - } - /* Remove queued buffers */ - while ((buf = gamma_waitlist_get(&q->waitlist))) { - gamma_free_buffer(dev, buf); - } - clear_bit(0, &dev->interrupt_flag); - - /* Wakeup blocked processes */ - wake_up_interruptible(&q->read_queue); - wake_up_interruptible(&q->write_queue); - wake_up_interruptible(&q->flush_queue); - - /* Finalization over. Queue is made - available when both use_count and - finalization become 0, which won't - happen until all the waiting processes - stop waiting. */ - atomic_dec(&q->finalization); - return 0; -} diff --git a/linux/gamma_dma.c b/linux/gamma_dma.c index eaff0473..eb394b2c 100644 --- a/linux/gamma_dma.c +++ b/linux/gamma_dma.c @@ -37,45 +37,32 @@ #include <linux/interrupt.h> /* For task queue support */ #include <linux/delay.h> -#if 0 -#define DO_IOREMAP( _map ) \ -do { \ - (_map)->handle = DRM(ioremap)( (_map)->offset, (_map)->size ); \ -} while (0) - -#define DO_IOREMAPFREE( _map ) \ -do { \ - if ( (_map)->handle && (_map)->size ) \ - DRM(ioremapfree)( (_map)->handle, (_map)->size ); \ -} while (0) - -#define DO_FIND_MAP( _map, _offset ) \ -do { \ - int _i; \ - for ( _i = 0 ; _i < dev->map_count ; _i++ ) { \ - if ( dev->maplist[_i]->offset == _offset ) { \ - _map = dev->maplist[_i]; \ - break; \ - } \ - } \ -} while (0) -#endif +#define OLDDMA 1 static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address, unsigned long length) { +#if OLDDMA GAMMA_WRITE(GAMMA_DMAADDRESS, virt_to_phys((void *)address)); - while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4) - ; + + while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4); + GAMMA_WRITE(GAMMA_DMACOUNT, length / 4); +#else + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 4); + + GAMMA_WRITE(GAMMA_OUTPUTFIFO, GAMMA_DMAADDRTAG); + GAMMA_WRITE(GAMMA_OUTPUTFIFO, virt_to_phys((void *)address)); + GAMMA_WRITE(GAMMA_OUTPUTFIFO, GAMMA_DMACOUNTTAG); + GAMMA_WRITE(GAMMA_OUTPUTFIFO, length / 4); +#endif } void gamma_dma_quiescent_single(drm_device_t *dev) { - while (GAMMA_READ(GAMMA_DMACOUNT)) - ; - while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) - ; + while (GAMMA_READ(GAMMA_DMACOUNT)); + + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 2); GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10); GAMMA_WRITE(GAMMA_SYNC, 0); @@ -88,39 +75,37 @@ void gamma_dma_quiescent_single(drm_device_t *dev) void gamma_dma_quiescent_dual(drm_device_t *dev) { - while (GAMMA_READ(GAMMA_DMACOUNT)) - ; - while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) - ; + while (GAMMA_READ(GAMMA_DMACOUNT)); + + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3); GAMMA_WRITE(GAMMA_BROADCASTMASK, 3); GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10); GAMMA_WRITE(GAMMA_SYNC, 0); - /* Read from first MX */ + /* Read from first MX */ do { - while (!GAMMA_READ(GAMMA_OUTFIFOWORDS)) - ; + while (!GAMMA_READ(GAMMA_OUTFIFOWORDS)); } while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG); - /* Read from second MX */ + /* Read from second MX */ do { - while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000)) - ; + while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000)); } while (GAMMA_READ(GAMMA_OUTPUTFIFO + 0x10000) != GAMMA_SYNC_TAG); } +#if OLDDMA void gamma_dma_ready(drm_device_t *dev) { - while (GAMMA_READ(GAMMA_DMACOUNT)) - ; + while (GAMMA_READ(GAMMA_DMACOUNT)); } static inline int gamma_dma_is_ready(drm_device_t *dev) { return !GAMMA_READ(GAMMA_DMACOUNT); } +#endif void gamma_dma_service(int irq, void *device, struct pt_regs *regs) { @@ -128,6 +113,8 @@ void gamma_dma_service(int irq, void *device, struct pt_regs *regs) drm_device_dma_t *dma = dev->dma; atomic_inc(&dev->counts[6]); /* _DRM_STAT_IRQ */ + +#if OLDDMA GAMMA_WRITE(GAMMA_GDELAYTIMER, 0xc350/2); /* 0x05S */ GAMMA_WRITE(GAMMA_GCOMMANDINTFLAGS, 8); GAMMA_WRITE(GAMMA_GINTFLAGS, 0x2001); @@ -144,6 +131,7 @@ void gamma_dma_service(int irq, void *device, struct pt_regs *regs) queue_task(&dev->tq, &tq_immediate); mark_bh(IMMEDIATE_BH); } +#endif } /* Only called by gamma_dma_schedule. */ @@ -287,12 +275,14 @@ int gamma_dma_schedule(drm_device_t *dev, int locked) cycles_t schedule_start; #endif +#if OLDDMA if (test_and_set_bit(0, &dev->interrupt_flag)) { /* Not reentrant */ atomic_inc(&dev->counts[10]); /* _DRM_STAT_MISSED */ return -EBUSY; } missed = atomic_read(&dev->counts[10]); +#endif #if DRM_DMA_HISTOGRAM schedule_start = get_cycles(); @@ -350,6 +340,7 @@ again: return retcode; } +#if OLDDMA static int gamma_dma_priority(drm_device_t *dev, drm_dma_t *d) { unsigned long address; @@ -487,6 +478,7 @@ cleanup: clear_bit(0, &dev->interrupt_flag); return retcode; } +#endif static int gamma_dma_send_buffers(drm_device_t *dev, drm_dma_t *d) { @@ -495,6 +487,7 @@ static int gamma_dma_send_buffers(drm_device_t *dev, drm_dma_t *d) int retcode = 0; drm_device_dma_t *dma = dev->dma; +#if OLDDMA if (d->flags & _DRM_DMA_BLOCK) { last_buf = dma->buflist[d->send_indices[d->send_count-1]]; add_wait_queue(&last_buf->dma_wait, &entry); @@ -541,6 +534,7 @@ static int gamma_dma_send_buffers(drm_device_t *dev, drm_dma_t *d) current->pid); } } +#endif return retcode; } @@ -553,10 +547,6 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd, int retcode = 0; drm_dma_t d; -#if 0 - LOCK_TEST_WITH_RETURN( dev ); -#endif - if (copy_from_user(&d, (drm_dma_t *)arg, sizeof(d))) return -EFAULT; @@ -573,9 +563,11 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd, } if (d.send_count) { +#if OLDDMA if (d.flags & _DRM_DMA_PRIORITY) retcode = gamma_dma_priority(dev, &d); else +#endif retcode = gamma_dma_send_buffers(dev, &d); } @@ -592,3 +584,160 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd, return retcode; } + +/* ================================================================ + * DMA initialization, cleanup + */ + +static int gamma_do_init_dma( drm_device_t *dev, drm_gamma_init_t *init ) +{ + drm_gamma_private_t *dev_priv; + int ret; + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + dev_priv = DRM(alloc)( sizeof(drm_gamma_private_t), DRM_MEM_DRIVER ); + if ( !dev_priv ) + return -ENOMEM; + dev->dev_private = (void *)dev_priv; + + memset( dev_priv, 0, sizeof(drm_gamma_private_t) ); + +#if 0 + dev_priv->chipset = init->chipset; + + dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT; + + if ( init->sgram ) { + dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_BLK; + } else { + dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR; + } + dev_priv->maccess = init->maccess; + + dev_priv->fb_cpp = init->fb_cpp; + dev_priv->front_offset = init->front_offset; + dev_priv->front_pitch = init->front_pitch; + dev_priv->back_offset = init->back_offset; + dev_priv->back_pitch = init->back_pitch; + + dev_priv->depth_cpp = init->depth_cpp; + dev_priv->depth_offset = init->depth_offset; + dev_priv->depth_pitch = init->depth_pitch; +#endif + + dev_priv->sarea = dev->maplist[0]; + +#if 0 + DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); + DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); + DRM_FIND_MAP( dev_priv->status, init->status_offset ); + + DRM_FIND_MAP( dev_priv->warp, init->warp_offset ); + DRM_FIND_MAP( dev_priv->primary, init->primary_offset ); +#endif + DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); + + dev_priv->sarea_priv = + (drm_gamma_sarea_t *)((u8 *)dev_priv->sarea->handle + + init->sarea_priv_offset); + +#if 0 + DRM_IOREMAP( dev_priv->warp ); + DRM_IOREMAP( dev_priv->primary ); +#endif + DRM_IOREMAP( dev_priv->buffers ); + +#if 0 + dev_priv->prim.status = (u32 *)dev_priv->status->handle; + + mga_do_wait_for_idle( dev_priv ); + + /* Init the primary DMA registers. + */ + MGA_WRITE( MGA_PRIMADDRESS, + dev_priv->primary->offset | MGA_DMA_GENERAL ); + + MGA_WRITE( MGA_PRIMPTR, + virt_to_bus((void *)dev_priv->prim.status) | + MGA_PRIMPTREN0 | /* Soft trap, SECEND, SETUPEND */ + MGA_PRIMPTREN1 ); /* DWGSYNC */ + + dev_priv->prim.start = (u8 *)dev_priv->primary->handle; + dev_priv->prim.end = ((u8 *)dev_priv->primary->handle + + dev_priv->primary->size); + dev_priv->prim.size = dev_priv->primary->size; + + dev_priv->prim.head = &dev_priv->prim.status[0]; + dev_priv->prim.tail = 0; + dev_priv->prim.space = dev_priv->prim.size; + + dev_priv->prim.last_flush = 0; + dev_priv->prim.last_wrap = 0; + + dev_priv->prim.high_mark = 256 * DMA_BLOCK_SIZE; + + spin_lock_init( &dev_priv->prim.list_lock ); + + dev_priv->prim.status[0] = dev_priv->primary->offset; + dev_priv->prim.status[1] = 0; + + dev_priv->sarea_priv->last_wrap = 0; + dev_priv->sarea_priv->last_frame.head = 0; + dev_priv->sarea_priv->last_frame.wrap = 0; + + if ( mga_freelist_init( dev ) < 0 ) { + DRM_ERROR( "could not initialize freelist\n" ); + mga_do_cleanup_dma( dev ); + return -ENOMEM; + } +#endif + + return 0; +} + +int gamma_do_cleanup_dma( drm_device_t *dev ) +{ + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + if ( dev->dev_private ) { + drm_gamma_private_t *dev_priv = dev->dev_private; + +#if 0 + DRM_IOREMAPFREE( dev_priv->warp ); + DRM_IOREMAPFREE( dev_priv->primary ); +#endif + DRM_IOREMAPFREE( dev_priv->buffers ); + +#if 0 + if ( dev_priv->head != NULL ) { + mga_freelist_cleanup( dev ); + } +#endif + + DRM(free)( dev->dev_private, sizeof(drm_gamma_private_t), + DRM_MEM_DRIVER ); + dev->dev_private = NULL; + } + + return 0; +} + +int gamma_dma_init( 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_gamma_init_t init; + + if ( copy_from_user( &init, (drm_gamma_init_t *)arg, sizeof(init) ) ) + return -EFAULT; + + switch ( init.func ) { + case GAMMA_INIT_DMA: + return gamma_do_init_dma( dev, &init ); + case GAMMA_CLEANUP_DMA: + return gamma_do_cleanup_dma( dev ); + } + + return -EINVAL; +} diff --git a/linux/gamma_drm.c b/linux/gamma_drm.c deleted file mode 100644 index 4b12d8c4..00000000 --- a/linux/gamma_drm.c +++ /dev/null @@ -1,33 +0,0 @@ -#define __NO_VERSION__ -#include "gamma.h" -#include "drmP.h" -#include "gamma_drv.h" - -#define DRIVER_DEV_PRIV_T drm_gamma_private_t -#define DRIVER_AGP_BUFFER_MAP dev_priv->buffers - -#include "drm_auth.h" - -#include "drm_bufs.h" - -#include "drm_dma.h" - -#include "drm_drawable.h" - -#include "drm_fops.h" - -#include "drm_init.h" - -#include "drm_ioctl.h" - -#include "drm_lists.h" - -#include "drm_lock.h" - -#include "drm_memory.h" - -#include "drm_proc.h" - -#include "drm_vm.h" - -#include "drm_stub.h" diff --git a/linux/gamma_drm.h b/linux/gamma_drm.h new file mode 100644 index 00000000..4be47ad4 --- /dev/null +++ b/linux/gamma_drm.h @@ -0,0 +1,48 @@ +typedef struct { + unsigned int GDeltaMode; + unsigned int GDepthMode; + unsigned int GGeometryMode; + unsigned int GTransformMode; +} drm_gamma_context_regs_t; + +typedef struct _drm_gamma_sarea { + drm_gamma_context_regs_t context_state; + + unsigned int dirty; + + int ctxOwner; +} drm_gamma_sarea_t; + +typedef struct drm_gamma_init { + enum { + GAMMA_INIT_DMA = 0x01, + GAMMA_CLEANUP_DMA = 0x02 + } func; + + int sarea_priv_offset; + +#if 0 + int chipset; + int sgram; + + unsigned int maccess; + + unsigned int fb_cpp; + unsigned int front_offset, front_pitch; + unsigned int back_offset, back_pitch; + + unsigned int depth_cpp; + unsigned int depth_offset, depth_pitch; + + unsigned int texture_offset[MGA_NR_TEX_HEAPS]; + unsigned int texture_size[MGA_NR_TEX_HEAPS]; + + unsigned int fb_offset; + unsigned int mmio_offset; + unsigned int status_offset; + unsigned int warp_offset; + unsigned int primary_offset; +#endif + unsigned int buffers_offset; +} drm_gamma_init_t; + diff --git a/linux/gamma_drv.c b/linux/gamma_drv.c index 98916bc5..0b91aedd 100644 --- a/linux/gamma_drv.c +++ b/linux/gamma_drv.c @@ -45,7 +45,8 @@ #define DRIVER_PATCHLEVEL 0 #define DRIVER_IOCTLS \ - [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { gamma_dma, 1, 0 } + [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { gamma_dma, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_GAMMA_INIT)] = { gamma_dma_init, 1, 1 } #define __HAVE_COUNTERS 5 @@ -57,6 +58,7 @@ #include "drm_auth.h" +#include "drm_agpsupport.h" #include "drm_bufs.h" #include "drm_context.h" #include "drm_dma.h" diff --git a/linux/gamma_drv.h b/linux/gamma_drv.h index d8cca667..627cdf41 100644 --- a/linux/gamma_drv.h +++ b/linux/gamma_drv.h @@ -34,6 +34,8 @@ typedef struct drm_gamma_private { + drm_gamma_sarea_t *sarea_priv; + drm_map_t *sarea; drm_map_t *buffers; } drm_gamma_private_t; @@ -47,6 +49,9 @@ do { \ } \ } while (0) + /* gamma_dma.c */ +extern int gamma_dma_init( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); extern void gamma_dma_ready(drm_device_t *dev); extern void gamma_dma_quiescent_single(drm_device_t *dev); @@ -103,4 +108,7 @@ extern int gamma_found(void); #define GAMMA_SYNC 0x8c40 #define GAMMA_SYNC_TAG 0x0188 +#define GAMMA_DMAADDRTAG 0x530 +#define GAMMA_DMACOUNTTAG 0x531 + #endif diff --git a/shared-core/drm.h b/shared-core/drm.h index 40a85875..4aa0d672 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -85,6 +85,7 @@ typedef struct drm_tex_region { #include "i810_drm.h" #include "r128_drm.h" #include "radeon_drm.h" +#include "gamma_drm.h" #ifdef CONFIG_DRM_SIS #include "sis_drm.h" #endif @@ -443,6 +444,9 @@ typedef struct drm_agp_info { #define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t) #define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t) +/* GAMMA specific ioctls */ +#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t) + #ifdef CONFIG_DRM_SIS /* SiS specific ioctls */ #define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t) diff --git a/shared/drm.h b/shared/drm.h index 40a85875..4aa0d672 100644 --- a/shared/drm.h +++ b/shared/drm.h @@ -85,6 +85,7 @@ typedef struct drm_tex_region { #include "i810_drm.h" #include "r128_drm.h" #include "radeon_drm.h" +#include "gamma_drm.h" #ifdef CONFIG_DRM_SIS #include "sis_drm.h" #endif @@ -443,6 +444,9 @@ typedef struct drm_agp_info { #define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t) #define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t) +/* GAMMA specific ioctls */ +#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t) + #ifdef CONFIG_DRM_SIS /* SiS specific ioctls */ #define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t) |