summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Hourihane <alanh@fairlite.demon.co.uk>2001-03-02 14:10:06 +0000
committerAlan Hourihane <alanh@fairlite.demon.co.uk>2001-03-02 14:10:06 +0000
commit4254e50a7249bc14ed148b60ac06db3306862eaa (patch)
tree89fd8a4e27bc73f1d55dbac669ddf16221e5e9a2
parent08a14259769b6291d2f62bdb2118a90f3896a9cf (diff)
downloaddrm-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.h2
-rw-r--r--linux/drm.h4
-rw-r--r--linux/drmP.h2
-rw-r--r--linux/gamma.h7
-rw-r--r--linux/gamma_context.c319
-rw-r--r--linux/gamma_dma.c239
-rw-r--r--linux/gamma_drm.c33
-rw-r--r--linux/gamma_drm.h48
-rw-r--r--linux/gamma_drv.c4
-rw-r--r--linux/gamma_drv.h8
-rw-r--r--shared-core/drm.h4
-rw-r--r--shared/drm.h4
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)