mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-26 04:10:17 +01:00
broken, checkpoint commit
This commit is contained in:
parent
bdd84e8958
commit
ca7e845cc9
13 changed files with 727 additions and 705 deletions
|
|
@ -26,7 +26,7 @@
|
|||
*
|
||||
* Authors: Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
* Jeff Hartmann <jhartmann@valinux.com>
|
||||
* Keith Whitwell <keithw@valinux.com>
|
||||
* Keith Whitwell <keith_whitwell@yahoo.com>
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -36,11 +36,6 @@
|
|||
#include "i810_drv.h"
|
||||
#include <linux/interrupt.h> /* For task queue support */
|
||||
|
||||
/* in case we don't have a 2.3.99-pre6 kernel or later: */
|
||||
#ifndef VM_DONTCOPY
|
||||
#define VM_DONTCOPY 0
|
||||
#endif
|
||||
|
||||
#define I810_BUF_FREE 2
|
||||
#define I810_BUF_CLIENT 1
|
||||
#define I810_BUF_HARDWARE 0
|
||||
|
|
@ -50,29 +45,27 @@
|
|||
|
||||
#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt;
|
||||
|
||||
#define BEGIN_LP_RING(n) do { \
|
||||
if (I810_VERBOSE) \
|
||||
DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \
|
||||
n, __FUNCTION__); \
|
||||
if (dev_priv->ring.space < n*4) \
|
||||
i810_wait_ring(dev, n*4); \
|
||||
dev_priv->ring.space -= n*4; \
|
||||
outring = dev_priv->ring.tail; \
|
||||
ringmask = dev_priv->ring.tail_mask; \
|
||||
virt = dev_priv->ring.virtual_start; \
|
||||
#define BEGIN_LP_RING(n) do { \
|
||||
if (0) DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \
|
||||
if (dev_priv->ring.space < n*4) \
|
||||
i810_wait_ring(dev, n*4); \
|
||||
dev_priv->ring.space -= n*4; \
|
||||
outring = dev_priv->ring.tail; \
|
||||
ringmask = dev_priv->ring.tail_mask; \
|
||||
virt = dev_priv->ring.virtual_start; \
|
||||
} while (0)
|
||||
|
||||
#define ADVANCE_LP_RING() do { \
|
||||
if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \
|
||||
dev_priv->ring.tail = outring; \
|
||||
I810_WRITE(LP_RING + RING_TAIL, outring); \
|
||||
#define ADVANCE_LP_RING() do { \
|
||||
if (0) 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) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
|
||||
*(volatile unsigned int *)(virt + outring) = n; \
|
||||
outring += 4; \
|
||||
outring &= ringmask; \
|
||||
#define OUT_RING(n) do { \
|
||||
if (0) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
|
||||
*(volatile unsigned int *)(virt + outring) = n; \
|
||||
outring += 4; \
|
||||
outring &= ringmask; \
|
||||
} while (0);
|
||||
|
||||
static inline void i810_print_status_page(drm_device_t *dev)
|
||||
|
|
@ -181,36 +174,31 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
|
|||
|
||||
if(buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL;
|
||||
|
||||
if(VM_DONTCOPY != 0) {
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
down( ¤t->mm->mmap_sem );
|
||||
down( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
down_write( ¤t->mm->mmap_sem );
|
||||
down_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
old_fops = filp->f_op;
|
||||
filp->f_op = &i810_buffer_fops;
|
||||
dev_priv->mmap_buffer = buf;
|
||||
buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total,
|
||||
PROT_READ|PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
buf->bus_address);
|
||||
dev_priv->mmap_buffer = NULL;
|
||||
filp->f_op = old_fops;
|
||||
if ((unsigned long)buf_priv->virtual > -1024UL) {
|
||||
/* Real error */
|
||||
DRM_DEBUG("mmap error\n");
|
||||
retcode = (signed int)buf_priv->virtual;
|
||||
buf_priv->virtual = 0;
|
||||
}
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
up( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
up_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
} else {
|
||||
buf_priv->virtual = buf_priv->kernel_virtual;
|
||||
buf_priv->currently_mapped = I810_BUF_MAPPED;
|
||||
old_fops = filp->f_op;
|
||||
filp->f_op = &i810_buffer_fops;
|
||||
dev_priv->mmap_buffer = buf;
|
||||
buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total,
|
||||
PROT_READ|PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
buf->bus_address);
|
||||
dev_priv->mmap_buffer = NULL;
|
||||
filp->f_op = old_fops;
|
||||
if ((unsigned long)buf_priv->virtual > -1024UL) {
|
||||
/* Real error */
|
||||
DRM_DEBUG("mmap error\n");
|
||||
retcode = (signed int)buf_priv->virtual;
|
||||
buf_priv->virtual = 0;
|
||||
}
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
up( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
up_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
|
@ -219,23 +207,21 @@ static int i810_unmap_buffer(drm_buf_t *buf)
|
|||
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
|
||||
int retcode = 0;
|
||||
|
||||
if(VM_DONTCOPY != 0) {
|
||||
if(buf_priv->currently_mapped != I810_BUF_MAPPED)
|
||||
return -EINVAL;
|
||||
if(buf_priv->currently_mapped != I810_BUF_MAPPED)
|
||||
return -EINVAL;
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
down( ¤t->mm->mmap_sem );
|
||||
down( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
down_write( ¤t->mm->mmap_sem );
|
||||
down_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
retcode = do_munmap(current->mm,
|
||||
(unsigned long)buf_priv->virtual,
|
||||
(size_t) buf->total);
|
||||
retcode = do_munmap(current->mm,
|
||||
(unsigned long)buf_priv->virtual,
|
||||
(size_t) buf->total);
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
up( ¤t->mm->mmap_sem );
|
||||
up( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
up_write( ¤t->mm->mmap_sem );
|
||||
up_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
}
|
||||
buf_priv->currently_mapped = I810_BUF_UNMAPPED;
|
||||
buf_priv->virtual = 0;
|
||||
|
||||
|
|
@ -444,9 +430,6 @@ static int i810_dma_initialize(drm_device_t *dev,
|
|||
((u8 *)dev_priv->sarea_map->handle +
|
||||
init->sarea_priv_offset);
|
||||
|
||||
atomic_set(&dev_priv->flush_done, 0);
|
||||
init_waitqueue_head(&dev_priv->flush_queue);
|
||||
|
||||
dev_priv->ring.Start = init->ring_start;
|
||||
dev_priv->ring.End = init->ring_end;
|
||||
dev_priv->ring.Size = init->ring_size;
|
||||
|
|
@ -536,16 +519,12 @@ int i810_dma_init(struct inode *inode, struct file *filp,
|
|||
|
||||
/* Most efficient way to verify state for the i810 is as it is
|
||||
* emitted. Non-conformant state is silently dropped.
|
||||
*
|
||||
* Use 'volatile' & local var tmp to force the emitted values to be
|
||||
* identical to the verified ones.
|
||||
*/
|
||||
static void i810EmitContextVerified( drm_device_t *dev,
|
||||
volatile unsigned int *code )
|
||||
unsigned int *code )
|
||||
{
|
||||
drm_i810_private_t *dev_priv = dev->dev_private;
|
||||
int i, j = 0;
|
||||
unsigned int tmp;
|
||||
RING_LOCALS;
|
||||
|
||||
BEGIN_LP_RING( I810_CTX_SETUP_SIZE );
|
||||
|
|
@ -557,12 +536,10 @@ static void i810EmitContextVerified( drm_device_t *dev,
|
|||
OUT_RING( code[I810_CTXREG_ST1] );
|
||||
|
||||
for ( i = 4 ; i < I810_CTX_SETUP_SIZE ; i++ ) {
|
||||
tmp = code[i];
|
||||
|
||||
if ((tmp & (7<<29)) == (3<<29) &&
|
||||
(tmp & (0x1f<<24)) < (0x1d<<24))
|
||||
if ((code[i] & (7<<29)) == (3<<29) &&
|
||||
(code[i] & (0x1f<<24)) < (0x1d<<24))
|
||||
{
|
||||
OUT_RING( tmp );
|
||||
OUT_RING( code[i] );
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
|
@ -578,7 +555,6 @@ static void i810EmitTexVerified( drm_device_t *dev,
|
|||
{
|
||||
drm_i810_private_t *dev_priv = dev->dev_private;
|
||||
int i, j = 0;
|
||||
unsigned int tmp;
|
||||
RING_LOCALS;
|
||||
|
||||
BEGIN_LP_RING( I810_TEX_SETUP_SIZE );
|
||||
|
|
@ -589,12 +565,11 @@ static void i810EmitTexVerified( drm_device_t *dev,
|
|||
OUT_RING( code[I810_TEXREG_MI3] );
|
||||
|
||||
for ( i = 4 ; i < I810_TEX_SETUP_SIZE ; i++ ) {
|
||||
tmp = code[i];
|
||||
|
||||
if ((tmp & (7<<29)) == (3<<29) &&
|
||||
(tmp & (0x1f<<24)) < (0x1d<<24))
|
||||
if ((code[i] & (7<<29)) == (3<<29) &&
|
||||
(code[i] & (0x1f<<24)) < (0x1d<<24))
|
||||
{
|
||||
OUT_RING( tmp );
|
||||
OUT_RING( code[i] );
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
|
@ -621,9 +596,7 @@ static void i810EmitDestVerified( drm_device_t *dev,
|
|||
if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) {
|
||||
OUT_RING( CMD_OP_DESTBUFFER_INFO );
|
||||
OUT_RING( tmp );
|
||||
} else
|
||||
DRM_DEBUG("bad di1 %x (allow %x or %x)\n",
|
||||
tmp, dev_priv->front_di1, dev_priv->back_di1);
|
||||
}
|
||||
|
||||
/* invarient:
|
||||
*/
|
||||
|
|
@ -645,30 +618,24 @@ static void i810EmitDestVerified( drm_device_t *dev,
|
|||
|
||||
|
||||
|
||||
static void i810EmitState( drm_device_t *dev )
|
||||
static void i810EmitState( drm_device_t *dev,
|
||||
drm_i810_state_t *state,
|
||||
unsigned int dirty )
|
||||
{
|
||||
drm_i810_private_t *dev_priv = dev->dev_private;
|
||||
drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
unsigned int dirty = sarea_priv->dirty;
|
||||
|
||||
if (dirty & I810_UPLOAD_BUFFERS) {
|
||||
i810EmitDestVerified( dev, sarea_priv->BufferState );
|
||||
sarea_priv->dirty &= ~I810_UPLOAD_BUFFERS;
|
||||
i810EmitDestVerified( dev, state->BufferSetup );
|
||||
}
|
||||
|
||||
if (dirty & I810_UPLOAD_CTX) {
|
||||
i810EmitContextVerified( dev, sarea_priv->ContextState );
|
||||
sarea_priv->dirty &= ~I810_UPLOAD_CTX;
|
||||
i810EmitContextVerified( dev, state->Setup );
|
||||
}
|
||||
|
||||
if (dirty & I810_UPLOAD_TEX0) {
|
||||
i810EmitTexVerified( dev, sarea_priv->TexState[0] );
|
||||
sarea_priv->dirty &= ~I810_UPLOAD_TEX0;
|
||||
i810EmitTexVerified( dev, state->TexSetup[0] );
|
||||
}
|
||||
|
||||
if (dirty & I810_UPLOAD_TEX1) {
|
||||
i810EmitTexVerified( dev, sarea_priv->TexState[1] );
|
||||
sarea_priv->dirty &= ~I810_UPLOAD_TEX1;
|
||||
i810EmitTexVerified( dev, state->TexSetup[1] );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -708,7 +675,6 @@ static void i810_dma_dispatch_clear( drm_device_t *dev, int flags,
|
|||
continue;
|
||||
|
||||
if ( flags & I810_FRONT ) {
|
||||
DRM_DEBUG("clear front\n");
|
||||
BEGIN_LP_RING( 6 );
|
||||
OUT_RING( BR00_BITBLT_CLIENT |
|
||||
BR00_OP_COLOR_BLT | 0x3 );
|
||||
|
|
@ -721,7 +687,6 @@ static void i810_dma_dispatch_clear( drm_device_t *dev, int flags,
|
|||
}
|
||||
|
||||
if ( flags & I810_BACK ) {
|
||||
DRM_DEBUG("clear back\n");
|
||||
BEGIN_LP_RING( 6 );
|
||||
OUT_RING( BR00_BITBLT_CLIENT |
|
||||
BR00_OP_COLOR_BLT | 0x3 );
|
||||
|
|
@ -734,7 +699,6 @@ static void i810_dma_dispatch_clear( drm_device_t *dev, int flags,
|
|||
}
|
||||
|
||||
if ( flags & I810_DEPTH ) {
|
||||
DRM_DEBUG("clear depth\n");
|
||||
BEGIN_LP_RING( 6 );
|
||||
OUT_RING( BR00_BITBLT_CLIENT |
|
||||
BR00_OP_COLOR_BLT | 0x3 );
|
||||
|
|
@ -760,8 +724,6 @@ static void i810_dma_dispatch_swap( drm_device_t *dev )
|
|||
int i;
|
||||
RING_LOCALS;
|
||||
|
||||
DRM_DEBUG("swapbuffers\n");
|
||||
|
||||
i810_kernel_lost_context(dev);
|
||||
|
||||
if (nbox > I810_NR_SAREA_CLIPRECTS)
|
||||
|
|
@ -780,10 +742,6 @@ static void i810_dma_dispatch_swap( drm_device_t *dev )
|
|||
pbox->y2 > dev_priv->h)
|
||||
continue;
|
||||
|
||||
DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n",
|
||||
pbox[i].x1, pbox[i].y1,
|
||||
pbox[i].x2, pbox[i].y2);
|
||||
|
||||
BEGIN_LP_RING( 6 );
|
||||
OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 );
|
||||
OUT_RING( pitch | (0xCC << 16));
|
||||
|
|
@ -799,7 +757,10 @@ static void i810_dma_dispatch_swap( drm_device_t *dev )
|
|||
static void i810_dma_dispatch_vertex(drm_device_t *dev,
|
||||
drm_buf_t *buf,
|
||||
int discard,
|
||||
int used)
|
||||
drm_i810_prim_t *prim,
|
||||
unsigned int nrprim,
|
||||
drm_i810_state_t *state,
|
||||
unsigned int nrstate )
|
||||
{
|
||||
drm_i810_private_t *dev_priv = dev->dev_private;
|
||||
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
|
||||
|
|
@ -807,139 +768,92 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev,
|
|||
drm_clip_rect_t *box = sarea_priv->boxes;
|
||||
int nbox = sarea_priv->nbox;
|
||||
unsigned long address = (unsigned long)buf->bus_address;
|
||||
unsigned long start = address - dev->agp->base;
|
||||
int i = 0, u;
|
||||
unsigned long bufstart = address - dev->agp->base;
|
||||
char *buf_virtual = (char *)buf_priv->virtual;
|
||||
unsigned int i;
|
||||
RING_LOCALS;
|
||||
|
||||
if (nbox > I810_NR_SAREA_CLIPRECTS)
|
||||
nrprim = 0;
|
||||
|
||||
i810_kernel_lost_context(dev);
|
||||
|
||||
if (nbox > I810_NR_SAREA_CLIPRECTS)
|
||||
nbox = I810_NR_SAREA_CLIPRECTS;
|
||||
for (i = 0 ; i < nrprim ; i++, prim++) {
|
||||
int j = 0;
|
||||
|
||||
if (discard) {
|
||||
u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
|
||||
I810_BUF_HARDWARE);
|
||||
if(u != I810_BUF_CLIENT) {
|
||||
DRM_DEBUG("xxxx 2\n");
|
||||
}
|
||||
}
|
||||
/* printk("prim %d start %x fin %x\n", i, prim->start, */
|
||||
/* prim->finish); */
|
||||
|
||||
if (used > 4*1024)
|
||||
used = 0;
|
||||
|
||||
if (sarea_priv->dirty)
|
||||
i810EmitState( dev );
|
||||
|
||||
DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n",
|
||||
address, used, nbox);
|
||||
|
||||
dev_priv->counter++;
|
||||
DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter);
|
||||
DRM_DEBUG( "i810_dma_dispatch\n");
|
||||
DRM_DEBUG( "start : %lx\n", start);
|
||||
DRM_DEBUG( "used : %d\n", used);
|
||||
DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4);
|
||||
|
||||
if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
|
||||
*(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE |
|
||||
sarea_priv->vertex_prim |
|
||||
((used/4)-2));
|
||||
|
||||
if (used & 4) {
|
||||
*(u32 *)((u32)buf_priv->virtual + used) = 0;
|
||||
used += 4;
|
||||
if ((unsigned)prim->start >= I810_DMA_BUF_SZ ||
|
||||
prim->start >= prim->finish ||
|
||||
(prim->start & 0x7) != 0x4) {
|
||||
/* printk("alignment/other\n"); */
|
||||
continue;
|
||||
}
|
||||
|
||||
i810_unmap_buffer(buf);
|
||||
}
|
||||
if (prim->dirty && prim->stateidx < nrstate) {
|
||||
i810EmitState( dev,
|
||||
&state[(int)prim->stateidx],
|
||||
prim->dirty );
|
||||
}
|
||||
|
||||
*(int *)&buf_virtual[prim->start-4] =
|
||||
(GFX_OP_PRIMITIVE | (((int)prim->prim) << 18) |
|
||||
((prim->finish - prim->start)/4-1));
|
||||
|
||||
|
||||
if (prim->finish & 0x4) {
|
||||
*(int *)&buf_virtual[prim->finish] = 0;
|
||||
prim->finish += 4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (used) {
|
||||
do {
|
||||
if (i < nbox) {
|
||||
if (j < nbox) {
|
||||
BEGIN_LP_RING(4);
|
||||
OUT_RING( GFX_OP_SCISSOR | SC_UPDATE_SCISSOR |
|
||||
OUT_RING( GFX_OP_SCISSOR |
|
||||
SC_UPDATE_SCISSOR |
|
||||
SC_ENABLE );
|
||||
OUT_RING( GFX_OP_SCISSOR_INFO );
|
||||
OUT_RING( box[i].x1 | (box[i].y1<<16) );
|
||||
OUT_RING( (box[i].x2-1) | ((box[i].y2-1)<<16) );
|
||||
OUT_RING( box[j].x1 | (box[j].y1<<16) );
|
||||
OUT_RING( (box[j].x2-1) | ((box[j].y2-1)<<16) );
|
||||
ADVANCE_LP_RING();
|
||||
if (nbox == 1) nbox = 0;
|
||||
}
|
||||
|
||||
BEGIN_LP_RING(4);
|
||||
OUT_RING( CMD_OP_BATCH_BUFFER );
|
||||
OUT_RING( start | BB1_PROTECTED );
|
||||
OUT_RING( start + used - 4 );
|
||||
OUT_RING( (bufstart + prim->start - 4) |
|
||||
BB1_PROTECTED );
|
||||
OUT_RING( (bufstart + prim->finish - 4) );
|
||||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
} while (++i < nbox);
|
||||
} while (++j < nbox);
|
||||
}
|
||||
|
||||
BEGIN_LP_RING(10);
|
||||
OUT_RING( CMD_STORE_DWORD_IDX );
|
||||
OUT_RING( 20 );
|
||||
OUT_RING( dev_priv->counter );
|
||||
OUT_RING( 0 );
|
||||
|
||||
if (discard) {
|
||||
dev_priv->counter++;
|
||||
|
||||
(void) cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
|
||||
I810_BUF_HARDWARE);
|
||||
|
||||
BEGIN_LP_RING( 8 );
|
||||
OUT_RING( CMD_STORE_DWORD_IDX );
|
||||
OUT_RING( 20 );
|
||||
OUT_RING( dev_priv->counter );
|
||||
OUT_RING( CMD_STORE_DWORD_IDX );
|
||||
OUT_RING( buf_priv->my_use_idx );
|
||||
OUT_RING( I810_BUF_FREE );
|
||||
OUT_RING( CMD_REPORT_HEAD );
|
||||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
||||
OUT_RING( CMD_REPORT_HEAD );
|
||||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
||||
|
||||
/* Interrupts are only for flushing */
|
||||
void i810_dma_service(int irq, void *device, struct pt_regs *regs)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)device;
|
||||
drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
|
||||
u16 temp;
|
||||
|
||||
atomic_inc(&dev->counts[_DRM_STAT_IRQ]);
|
||||
temp = I810_READ16(I810REG_INT_IDENTITY_R);
|
||||
temp = temp & ~(0x6000);
|
||||
if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R,
|
||||
temp); /* Clear all interrupts */
|
||||
else
|
||||
return;
|
||||
|
||||
queue_task(&dev->tq, &tq_immediate);
|
||||
mark_bh(IMMEDIATE_BH);
|
||||
}
|
||||
|
||||
void i810_dma_immediate_bh(void *device)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *) device;
|
||||
drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
|
||||
|
||||
atomic_set(&dev_priv->flush_done, 1);
|
||||
wake_up_interruptible(&dev_priv->flush_queue);
|
||||
}
|
||||
|
||||
static inline void i810_dma_emit_flush(drm_device_t *dev)
|
||||
{
|
||||
drm_i810_private_t *dev_priv = dev->dev_private;
|
||||
RING_LOCALS;
|
||||
|
||||
i810_kernel_lost_context(dev);
|
||||
|
||||
BEGIN_LP_RING(2);
|
||||
OUT_RING( CMD_REPORT_HEAD );
|
||||
OUT_RING( GFX_OP_USER_INTERRUPT );
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
/* i810_wait_ring( dev, dev_priv->ring.Size - 8 ); */
|
||||
/* atomic_set(&dev_priv->flush_done, 1); */
|
||||
/* wake_up_interruptible(&dev_priv->flush_queue); */
|
||||
}
|
||||
|
||||
static inline void i810_dma_quiescent_emit(drm_device_t *dev)
|
||||
void i810_dma_quiescent(drm_device_t *dev)
|
||||
{
|
||||
drm_i810_private_t *dev_priv = dev->dev_private;
|
||||
RING_LOCALS;
|
||||
|
|
@ -950,79 +864,27 @@ static inline void i810_dma_quiescent_emit(drm_device_t *dev)
|
|||
OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
|
||||
OUT_RING( CMD_REPORT_HEAD );
|
||||
OUT_RING( 0 );
|
||||
OUT_RING( GFX_OP_USER_INTERRUPT );
|
||||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
/* i810_wait_ring( dev, dev_priv->ring.Size - 8 ); */
|
||||
/* atomic_set(&dev_priv->flush_done, 1); */
|
||||
/* wake_up_interruptible(&dev_priv->flush_queue); */
|
||||
}
|
||||
|
||||
void i810_dma_quiescent(drm_device_t *dev)
|
||||
{
|
||||
DECLARE_WAITQUEUE(entry, current);
|
||||
drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
|
||||
unsigned long end;
|
||||
|
||||
if(dev_priv == NULL) {
|
||||
return;
|
||||
}
|
||||
atomic_set(&dev_priv->flush_done, 0);
|
||||
add_wait_queue(&dev_priv->flush_queue, &entry);
|
||||
end = jiffies + (HZ*3);
|
||||
|
||||
for (;;) {
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
i810_dma_quiescent_emit(dev);
|
||||
if (atomic_read(&dev_priv->flush_done) == 1) break;
|
||||
if((signed)(end - jiffies) <= 0) {
|
||||
DRM_ERROR("lockup\n");
|
||||
break;
|
||||
}
|
||||
schedule_timeout(HZ*3);
|
||||
if (signal_pending(current)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
current->state = TASK_RUNNING;
|
||||
remove_wait_queue(&dev_priv->flush_queue, &entry);
|
||||
|
||||
return;
|
||||
i810_wait_ring( dev, dev_priv->ring.Size - 8 );
|
||||
}
|
||||
|
||||
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;
|
||||
drm_i810_private_t *dev_priv = dev->dev_private;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
unsigned long end;
|
||||
int i, ret = 0;
|
||||
RING_LOCALS;
|
||||
|
||||
i810_kernel_lost_context(dev);
|
||||
|
||||
if(dev_priv == NULL) {
|
||||
return 0;
|
||||
}
|
||||
atomic_set(&dev_priv->flush_done, 0);
|
||||
add_wait_queue(&dev_priv->flush_queue, &entry);
|
||||
end = jiffies + (HZ*3);
|
||||
for (;;) {
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
i810_dma_emit_flush(dev);
|
||||
if (atomic_read(&dev_priv->flush_done) == 1) break;
|
||||
if((signed)(end - jiffies) <= 0) {
|
||||
DRM_ERROR("lockup\n");
|
||||
break;
|
||||
}
|
||||
schedule_timeout(HZ*3);
|
||||
if (signal_pending(current)) {
|
||||
ret = -EINTR; /* Can't restart */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
current->state = TASK_RUNNING;
|
||||
remove_wait_queue(&dev_priv->flush_queue, &entry);
|
||||
BEGIN_LP_RING(2);
|
||||
OUT_RING( CMD_REPORT_HEAD );
|
||||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
i810_wait_ring( dev, dev_priv->ring.Size - 8 );
|
||||
|
||||
for (i = 0; i < dma->buf_count; i++) {
|
||||
drm_buf_t *buf = dma->buflist[ i ];
|
||||
|
|
@ -1034,7 +896,7 @@ static int i810_flush_queue(drm_device_t *dev)
|
|||
if (used == I810_BUF_HARDWARE)
|
||||
DRM_DEBUG("reclaimed from HARDWARE\n");
|
||||
if (used == I810_BUF_CLIENT)
|
||||
DRM_DEBUG("still on client HARDWARE\n");
|
||||
DRM_DEBUG("still on client\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -1074,7 +936,6 @@ int i810_flush_ioctl(struct inode *inode, struct file *filp,
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
|
||||
DRM_DEBUG("i810_flush_ioctl\n");
|
||||
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
||||
DRM_ERROR("i810_flush_ioctl called without lock held\n");
|
||||
return -EINVAL;
|
||||
|
|
@ -1085,8 +946,32 @@ int i810_flush_ioctl(struct inode *inode, struct file *filp,
|
|||
}
|
||||
|
||||
|
||||
/* Copy sarea data into temporary structs.
|
||||
*/
|
||||
void i810_copy_state( drm_i810_sarea_t *sarea, drm_i810_state_t *state )
|
||||
{
|
||||
if (sarea->dirty & I810_UPLOAD_CTX)
|
||||
memcpy(state->Setup, sarea->ContextState,
|
||||
sizeof(state->Setup));
|
||||
|
||||
if (sarea->dirty & I810_UPLOAD_BUFFERS)
|
||||
memcpy(state->BufferSetup, sarea->BufferState,
|
||||
sizeof(state->BufferSetup));
|
||||
|
||||
if (sarea->dirty & I810_UPLOAD_TEX0)
|
||||
memcpy(state->TexSetup[0], sarea->TexState[0],
|
||||
sizeof(state->TexSetup[0]));
|
||||
|
||||
if (sarea->dirty & I810_UPLOAD_TEX1)
|
||||
memcpy(state->TexSetup[1], sarea->TexState[1],
|
||||
sizeof(state->TexSetup[1]));
|
||||
}
|
||||
|
||||
|
||||
/* Obsolete, backwards compatibility ioctl:
|
||||
*/
|
||||
int i810_dma_vertex(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;
|
||||
|
|
@ -1096,6 +981,12 @@ int i810_dma_vertex(struct inode *inode, struct file *filp,
|
|||
drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
|
||||
dev_priv->sarea_priv;
|
||||
drm_i810_vertex_t vertex;
|
||||
drm_buf_t *buf;
|
||||
drm_i810_buf_priv_t *buf_priv;
|
||||
drm_i810_state_t tmpstate;
|
||||
drm_i810_prim_t tmpprim;
|
||||
|
||||
/* printk("%s\n", __FUNCTION__); */
|
||||
|
||||
if (copy_from_user(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex)))
|
||||
return -EFAULT;
|
||||
|
|
@ -1105,24 +996,116 @@ int i810_dma_vertex(struct inode *inode, struct file *filp,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n",
|
||||
vertex.idx, vertex.used, vertex.discard);
|
||||
buf = dma->buflist[ vertex.idx ];
|
||||
buf_priv = buf->dev_private;
|
||||
|
||||
if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL;
|
||||
if (vertex.idx < 0 || vertex.idx >= I810_DMA_BUF_NR) {
|
||||
DRM_ERROR("i810_dma_vertex2 bad buffer idx\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (sarea_priv->dirty)
|
||||
i810_copy_state( sarea_priv, &tmpstate );
|
||||
|
||||
i810_dma_dispatch_vertex( dev,
|
||||
dma->buflist[ vertex.idx ],
|
||||
vertex.discard, vertex.used );
|
||||
tmpprim.start = 0;
|
||||
tmpprim.finish = vertex.used;
|
||||
tmpprim.prim = (char) sarea_priv->vertex_prim;
|
||||
tmpprim.dirty = (char) sarea_priv->dirty;
|
||||
tmpprim.stateidx = 0;
|
||||
|
||||
i810_dma_dispatch_vertex( dev, buf,
|
||||
vertex.discard,
|
||||
&tmpprim, 1,
|
||||
&tmpstate, 1 );
|
||||
|
||||
if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
|
||||
i810_unmap_buffer(buf);
|
||||
}
|
||||
|
||||
atomic_add(vertex.used, &dev->counts[_DRM_STAT_SECONDARY]);
|
||||
atomic_inc(&dev->counts[_DRM_STAT_DMA]);
|
||||
|
||||
sarea_priv->last_enqueue = dev_priv->counter-1;
|
||||
sarea_priv->last_dispatch = (int) hw_status[5];
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int i810_dma_vertex2(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_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
|
||||
u32 *hw_status = (u32 *)dev_priv->hw_status_page;
|
||||
drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
|
||||
dev_priv->sarea_priv;
|
||||
drm_i810_vertex2_t vertex;
|
||||
drm_buf_t *buf;
|
||||
drm_i810_buf_priv_t *buf_priv;
|
||||
|
||||
/* printk("%s\n", __FUNCTION__); */
|
||||
|
||||
if (copy_from_user(&vertex, (drm_i810_vertex2_t *)arg, sizeof(vertex)))
|
||||
return -EFAULT;
|
||||
|
||||
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
||||
DRM_ERROR("i810_dma_vertex2 called without lock held\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (vertex.idx >= I810_DMA_BUF_NR) {
|
||||
DRM_ERROR("i810_dma_vertex2 bad buffer idx\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
/* printk("%s buf %d nstates %d nprim %d\n", */
|
||||
/* __FUNCTION__, */
|
||||
/* vertex.idx, */
|
||||
/* vertex.nr_states, */
|
||||
/* vertex.nr_prims ); */
|
||||
|
||||
buf = dma->buflist[ vertex.idx ];
|
||||
buf_priv = buf->dev_private;
|
||||
|
||||
if (vertex.nr_states) {
|
||||
if (vertex.nr_states >= I810_MAX_STATES)
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(dev_priv->statetmp,
|
||||
vertex.state_address,
|
||||
vertex.nr_states * sizeof(drm_i810_state_t)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (vertex.nr_prims) {
|
||||
if (vertex.nr_prims >= I810_MAX_PRIMS)
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(dev_priv->primtmp,
|
||||
vertex.prim_address,
|
||||
vertex.nr_prims * sizeof(drm_i810_prim_t)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
i810_dma_dispatch_vertex( dev, buf,
|
||||
vertex.discard,
|
||||
dev_priv->primtmp,
|
||||
vertex.nr_prims,
|
||||
dev_priv->statetmp,
|
||||
vertex.nr_states );
|
||||
|
||||
if (buf_priv->currently_mapped == I810_BUF_MAPPED)
|
||||
i810_unmap_buffer(buf);
|
||||
|
||||
atomic_inc(&dev->counts[_DRM_STAT_DMA]);
|
||||
|
||||
sarea_priv->last_enqueue = dev_priv->counter-1;
|
||||
sarea_priv->last_dispatch = (int) hw_status[5];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int i810_clear_bufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
|
|
@ -1156,8 +1139,6 @@ int i810_swap_bufs(struct inode *inode, struct file *filp,
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
|
||||
DRM_DEBUG("i810_swap_bufs\n");
|
||||
|
||||
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
||||
DRM_ERROR("i810_swap_buf called without lock held\n");
|
||||
return -EINVAL;
|
||||
|
|
@ -1193,7 +1174,6 @@ int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
|
||||
dev_priv->sarea_priv;
|
||||
|
||||
DRM_DEBUG("getbuf\n");
|
||||
if (copy_from_user(&d, (drm_i810_dma_t *)arg, sizeof(d)))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
@ -1206,9 +1186,6 @@ int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
|
||||
retcode = i810_dma_get_buffer(dev, &d, filp);
|
||||
|
||||
DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n",
|
||||
current->pid, retcode, d.granted);
|
||||
|
||||
if (copy_to_user((drm_dma_t *)arg, &d, sizeof(d)))
|
||||
return -EFAULT;
|
||||
sarea_priv->last_dispatch = (int) hw_status[5];
|
||||
|
|
@ -1216,46 +1193,18 @@ int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
return retcode;
|
||||
}
|
||||
|
||||
int i810_copybuf(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
int i810_copybuf(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_i810_copy_t d;
|
||||
drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
|
||||
u32 *hw_status = (u32 *)dev_priv->hw_status_page;
|
||||
drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
|
||||
dev_priv->sarea_priv;
|
||||
drm_buf_t *buf;
|
||||
drm_i810_buf_priv_t *buf_priv;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
|
||||
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
||||
DRM_ERROR("i810_dma called without lock held\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (copy_from_user(&d, (drm_i810_copy_t *)arg, sizeof(d)))
|
||||
return -EFAULT;
|
||||
|
||||
if(d.idx < 0 || d.idx > dma->buf_count) return -EINVAL;
|
||||
buf = dma->buflist[ d.idx ];
|
||||
buf_priv = buf->dev_private;
|
||||
if (buf_priv->currently_mapped != I810_BUF_MAPPED) return -EPERM;
|
||||
|
||||
if(d.used < 0 || d.used > buf->total) return -EINVAL;
|
||||
|
||||
if (copy_from_user(buf_priv->virtual, d.address, d.used))
|
||||
return -EFAULT;
|
||||
|
||||
sarea_priv->last_dispatch = (int) hw_status[5];
|
||||
|
||||
/* Never copy - 2.4.x doesn't need it */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i810_docopy(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
if(VM_DONTCOPY == 0) return 1;
|
||||
/* Never copy - 2.4.x doesn't need it */
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,6 +88,8 @@
|
|||
#define I810_TEXREG_MCS 7 /* GFX_OP_MAP_COORD_SETS ??? */
|
||||
#define I810_TEX_SETUP_SIZE 8
|
||||
|
||||
/* Flags for clear ioctl
|
||||
*/
|
||||
#define I810_FRONT 0x1
|
||||
#define I810_BACK 0x2
|
||||
#define I810_DEPTH 0x4
|
||||
|
|
@ -189,6 +191,52 @@ typedef struct _drm_i810_copy_t {
|
|||
void *address; /* Address to copy from */
|
||||
} drm_i810_copy_t;
|
||||
|
||||
|
||||
typedef struct _drm_i810_state {
|
||||
unsigned int Setup[I810_CTX_SETUP_SIZE];
|
||||
unsigned int BufferSetup[I810_DEST_SETUP_SIZE];
|
||||
unsigned int TexSetup[2][I810_TEX_SETUP_SIZE];
|
||||
} drm_i810_state_t;
|
||||
|
||||
#define PR_TRIANGLES (0x0)
|
||||
#define PR_TRISTRIP_0 (0x1)
|
||||
#define PR_TRISTRIP_1 (0x2)
|
||||
#define PR_TRIFAN (0x3)
|
||||
#define PR_POLYGON (0x4)
|
||||
#define PR_LINES (0x5)
|
||||
#define PR_LINESTRIP (0x6)
|
||||
#define PR_RECTS (0x7)
|
||||
|
||||
typedef struct _drm_i810_prim {
|
||||
int start;
|
||||
int finish;
|
||||
char prim;
|
||||
char dirty;
|
||||
char stateidx;
|
||||
} drm_i810_prim_t;
|
||||
|
||||
|
||||
#define I810_MAX_PRIMS 100
|
||||
#define I810_MAX_STATES 20
|
||||
|
||||
/* Still uses the sarea to pass cliprects (fix?). State and primitive
|
||||
* information are passed directly as pointers to userspace data.
|
||||
* Copying of vertex data is performed by this ioctl as well.
|
||||
*
|
||||
* This obsoletes _drm_i810_vertex, _drm_i810_copy and the state and
|
||||
* primitive fields in the sarea.
|
||||
*/
|
||||
typedef struct _drm_i810_vertex2 {
|
||||
unsigned int idx; /* buffer index */
|
||||
unsigned int discard; /* client is finished with the buffer? */
|
||||
void *vertex_address;
|
||||
unsigned int nr_states;
|
||||
drm_i810_state_t *state_address;
|
||||
unsigned int nr_prims;
|
||||
drm_i810_prim_t *prim_address;
|
||||
} drm_i810_vertex2_t;
|
||||
|
||||
|
||||
typedef struct drm_i810_dma {
|
||||
void *virtual;
|
||||
int request_idx;
|
||||
|
|
|
|||
|
|
@ -54,7 +54,8 @@
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)] = { i810_swap_bufs, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)] = { i810_copybuf, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX2)] = { i810_dma_vertex2, 1, 0 },
|
||||
|
||||
|
||||
#define __HAVE_COUNTERS 4
|
||||
|
|
|
|||
|
|
@ -64,8 +64,6 @@ typedef struct drm_i810_private {
|
|||
unsigned long hw_status_page;
|
||||
unsigned long counter;
|
||||
|
||||
atomic_t flush_done;
|
||||
wait_queue_head_t flush_queue; /* Processes waiting until flush */
|
||||
drm_buf_t *mmap_buffer;
|
||||
|
||||
|
||||
|
|
@ -75,6 +73,12 @@ typedef struct drm_i810_private {
|
|||
int depth_offset;
|
||||
int w, h;
|
||||
int pitch;
|
||||
|
||||
/* Temporaries to hold userspace data before submitting to the
|
||||
* ring.
|
||||
*/
|
||||
drm_i810_state_t statetmp[I810_MAX_STATES];
|
||||
drm_i810_prim_t primtmp[I810_MAX_STATES];
|
||||
} drm_i810_private_t;
|
||||
|
||||
/* i810_dma.c */
|
||||
|
|
@ -89,19 +93,29 @@ extern void i810_reclaim_buffers(drm_device_t *dev, pid_t pid);
|
|||
extern int i810_getage(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma);
|
||||
|
||||
/* Obsolete:
|
||||
*/
|
||||
extern int i810_copybuf(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
/* Obsolete:
|
||||
*/
|
||||
extern int i810_docopy(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
extern void i810_dma_quiescent(drm_device_t *dev);
|
||||
|
||||
#define I810_VERBOSE 0
|
||||
|
||||
|
||||
/* Obsolete
|
||||
*/
|
||||
int i810_dma_vertex(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
/* Handles multiple prims/ioctl, does any necessary copying in this
|
||||
* ioctl:
|
||||
*/
|
||||
int i810_dma_vertex2(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
int i810_swap_bufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
|
|
|
|||
|
|
@ -104,6 +104,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
|
||||
|
|
@ -449,6 +450,7 @@ typedef struct drm_scatter_gather {
|
|||
#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46)
|
||||
#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
|
||||
#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48)
|
||||
#define DRM_IOCTL_I810_VERTEX2 DRM_IOW( 0x49, drm_i810_vertex2_t)
|
||||
|
||||
/* Rage 128 specific ioctls */
|
||||
#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
|
||||
|
|
@ -466,6 +468,7 @@ typedef struct drm_scatter_gather {
|
|||
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
|
||||
#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
|
||||
#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t)
|
||||
#define DRM_IOCTL_R128_CLEAR2 DRM_IOW( 0x51, drm_r128_clear2_t)
|
||||
|
||||
/* Radeon specific ioctls */
|
||||
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t)
|
||||
|
|
@ -483,6 +486,10 @@ typedef struct drm_scatter_gather {
|
|||
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
|
||||
#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t)
|
||||
|
||||
/* Gamma specific ioctls */
|
||||
#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t)
|
||||
#define DRM_IOCTL_GAMMA_COPY DRM_IOW( 0x41, drm_gamma_copy_t)
|
||||
|
||||
#ifdef CONFIG_DRM_SIS
|
||||
/* SiS specific ioctls */
|
||||
#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t)
|
||||
|
|
|
|||
47
linux/i810.h
47
linux/i810.h
|
|
@ -60,50 +60,9 @@
|
|||
i810_dma_quiescent( dev ); \
|
||||
} while (0)
|
||||
|
||||
#define __HAVE_DMA_IRQ 1
|
||||
#define __HAVE_DMA_IRQ_BH 1
|
||||
#define __HAVE_SHARED_IRQ 1
|
||||
#define DRIVER_PREINSTALL() do { \
|
||||
drm_i810_private_t *dev_priv = \
|
||||
(drm_i810_private_t *)dev->dev_private; \
|
||||
u16 tmp; \
|
||||
tmp = I810_READ16( I810REG_HWSTAM ); \
|
||||
tmp = tmp & 0x6000; \
|
||||
I810_WRITE16( I810REG_HWSTAM, tmp ); \
|
||||
\
|
||||
tmp = I810_READ16( I810REG_INT_MASK_R ); \
|
||||
tmp = tmp & 0x6000; /* Unmask interrupts */ \
|
||||
I810_WRITE16( I810REG_INT_MASK_R, tmp ); \
|
||||
tmp = I810_READ16( I810REG_INT_ENABLE_R ); \
|
||||
tmp = tmp & 0x6000; /* Disable all interrupts */ \
|
||||
I810_WRITE16( I810REG_INT_ENABLE_R, tmp ); \
|
||||
} while (0)
|
||||
|
||||
#define DRIVER_POSTINSTALL() do { \
|
||||
drm_i810_private_t *dev_priv = \
|
||||
(drm_i810_private_t *)dev->dev_private; \
|
||||
u16 tmp; \
|
||||
tmp = I810_READ16( I810REG_INT_ENABLE_R ); \
|
||||
tmp = tmp & 0x6000; \
|
||||
tmp = tmp | 0x0003; /* Enable bp & user interrupts */ \
|
||||
I810_WRITE16( I810REG_INT_ENABLE_R, tmp ); \
|
||||
} while (0)
|
||||
|
||||
#define DRIVER_UNINSTALL() do { \
|
||||
drm_i810_private_t *dev_priv = \
|
||||
(drm_i810_private_t *)dev->dev_private; \
|
||||
u16 tmp; \
|
||||
if ( dev_priv ) { \
|
||||
tmp = I810_READ16( I810REG_INT_IDENTITY_R ); \
|
||||
tmp = tmp & ~(0x6000); /* Clear all interrupts */ \
|
||||
if ( tmp != 0 ) \
|
||||
I810_WRITE16( I810REG_INT_IDENTITY_R, tmp ); \
|
||||
\
|
||||
tmp = I810_READ16( I810REG_INT_ENABLE_R ); \
|
||||
tmp = tmp & 0x6000; /* Disable all interrupts */ \
|
||||
I810_WRITE16( I810REG_INT_ENABLE_R, tmp ); \
|
||||
} \
|
||||
} while (0)
|
||||
#define __HAVE_DMA_IRQ 0
|
||||
#define __HAVE_DMA_IRQ_BH 0
|
||||
#define __HAVE_SHARED_IRQ 1
|
||||
|
||||
/* Buffer customization:
|
||||
*/
|
||||
|
|
|
|||
593
linux/i810_dma.c
593
linux/i810_dma.c
|
|
@ -26,7 +26,7 @@
|
|||
*
|
||||
* Authors: Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
* Jeff Hartmann <jhartmann@valinux.com>
|
||||
* Keith Whitwell <keithw@valinux.com>
|
||||
* Keith Whitwell <keith_whitwell@yahoo.com>
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -36,11 +36,6 @@
|
|||
#include "i810_drv.h"
|
||||
#include <linux/interrupt.h> /* For task queue support */
|
||||
|
||||
/* in case we don't have a 2.3.99-pre6 kernel or later: */
|
||||
#ifndef VM_DONTCOPY
|
||||
#define VM_DONTCOPY 0
|
||||
#endif
|
||||
|
||||
#define I810_BUF_FREE 2
|
||||
#define I810_BUF_CLIENT 1
|
||||
#define I810_BUF_HARDWARE 0
|
||||
|
|
@ -50,29 +45,27 @@
|
|||
|
||||
#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt;
|
||||
|
||||
#define BEGIN_LP_RING(n) do { \
|
||||
if (I810_VERBOSE) \
|
||||
DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \
|
||||
n, __FUNCTION__); \
|
||||
if (dev_priv->ring.space < n*4) \
|
||||
i810_wait_ring(dev, n*4); \
|
||||
dev_priv->ring.space -= n*4; \
|
||||
outring = dev_priv->ring.tail; \
|
||||
ringmask = dev_priv->ring.tail_mask; \
|
||||
virt = dev_priv->ring.virtual_start; \
|
||||
#define BEGIN_LP_RING(n) do { \
|
||||
if (0) DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \
|
||||
if (dev_priv->ring.space < n*4) \
|
||||
i810_wait_ring(dev, n*4); \
|
||||
dev_priv->ring.space -= n*4; \
|
||||
outring = dev_priv->ring.tail; \
|
||||
ringmask = dev_priv->ring.tail_mask; \
|
||||
virt = dev_priv->ring.virtual_start; \
|
||||
} while (0)
|
||||
|
||||
#define ADVANCE_LP_RING() do { \
|
||||
if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \
|
||||
dev_priv->ring.tail = outring; \
|
||||
I810_WRITE(LP_RING + RING_TAIL, outring); \
|
||||
#define ADVANCE_LP_RING() do { \
|
||||
if (0) 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) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
|
||||
*(volatile unsigned int *)(virt + outring) = n; \
|
||||
outring += 4; \
|
||||
outring &= ringmask; \
|
||||
#define OUT_RING(n) do { \
|
||||
if (0) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
|
||||
*(volatile unsigned int *)(virt + outring) = n; \
|
||||
outring += 4; \
|
||||
outring &= ringmask; \
|
||||
} while (0);
|
||||
|
||||
static inline void i810_print_status_page(drm_device_t *dev)
|
||||
|
|
@ -181,36 +174,31 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
|
|||
|
||||
if(buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL;
|
||||
|
||||
if(VM_DONTCOPY != 0) {
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
down( ¤t->mm->mmap_sem );
|
||||
down( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
down_write( ¤t->mm->mmap_sem );
|
||||
down_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
old_fops = filp->f_op;
|
||||
filp->f_op = &i810_buffer_fops;
|
||||
dev_priv->mmap_buffer = buf;
|
||||
buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total,
|
||||
PROT_READ|PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
buf->bus_address);
|
||||
dev_priv->mmap_buffer = NULL;
|
||||
filp->f_op = old_fops;
|
||||
if ((unsigned long)buf_priv->virtual > -1024UL) {
|
||||
/* Real error */
|
||||
DRM_DEBUG("mmap error\n");
|
||||
retcode = (signed int)buf_priv->virtual;
|
||||
buf_priv->virtual = 0;
|
||||
}
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
up( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
up_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
} else {
|
||||
buf_priv->virtual = buf_priv->kernel_virtual;
|
||||
buf_priv->currently_mapped = I810_BUF_MAPPED;
|
||||
old_fops = filp->f_op;
|
||||
filp->f_op = &i810_buffer_fops;
|
||||
dev_priv->mmap_buffer = buf;
|
||||
buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total,
|
||||
PROT_READ|PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
buf->bus_address);
|
||||
dev_priv->mmap_buffer = NULL;
|
||||
filp->f_op = old_fops;
|
||||
if ((unsigned long)buf_priv->virtual > -1024UL) {
|
||||
/* Real error */
|
||||
DRM_DEBUG("mmap error\n");
|
||||
retcode = (signed int)buf_priv->virtual;
|
||||
buf_priv->virtual = 0;
|
||||
}
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
up( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
up_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
|
@ -219,23 +207,21 @@ static int i810_unmap_buffer(drm_buf_t *buf)
|
|||
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
|
||||
int retcode = 0;
|
||||
|
||||
if(VM_DONTCOPY != 0) {
|
||||
if(buf_priv->currently_mapped != I810_BUF_MAPPED)
|
||||
return -EINVAL;
|
||||
if(buf_priv->currently_mapped != I810_BUF_MAPPED)
|
||||
return -EINVAL;
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
down( ¤t->mm->mmap_sem );
|
||||
down( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
down_write( ¤t->mm->mmap_sem );
|
||||
down_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
retcode = do_munmap(current->mm,
|
||||
(unsigned long)buf_priv->virtual,
|
||||
(size_t) buf->total);
|
||||
retcode = do_munmap(current->mm,
|
||||
(unsigned long)buf_priv->virtual,
|
||||
(size_t) buf->total);
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
up( ¤t->mm->mmap_sem );
|
||||
up( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
up_write( ¤t->mm->mmap_sem );
|
||||
up_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
}
|
||||
buf_priv->currently_mapped = I810_BUF_UNMAPPED;
|
||||
buf_priv->virtual = 0;
|
||||
|
||||
|
|
@ -444,9 +430,6 @@ static int i810_dma_initialize(drm_device_t *dev,
|
|||
((u8 *)dev_priv->sarea_map->handle +
|
||||
init->sarea_priv_offset);
|
||||
|
||||
atomic_set(&dev_priv->flush_done, 0);
|
||||
init_waitqueue_head(&dev_priv->flush_queue);
|
||||
|
||||
dev_priv->ring.Start = init->ring_start;
|
||||
dev_priv->ring.End = init->ring_end;
|
||||
dev_priv->ring.Size = init->ring_size;
|
||||
|
|
@ -536,16 +519,12 @@ int i810_dma_init(struct inode *inode, struct file *filp,
|
|||
|
||||
/* Most efficient way to verify state for the i810 is as it is
|
||||
* emitted. Non-conformant state is silently dropped.
|
||||
*
|
||||
* Use 'volatile' & local var tmp to force the emitted values to be
|
||||
* identical to the verified ones.
|
||||
*/
|
||||
static void i810EmitContextVerified( drm_device_t *dev,
|
||||
volatile unsigned int *code )
|
||||
unsigned int *code )
|
||||
{
|
||||
drm_i810_private_t *dev_priv = dev->dev_private;
|
||||
int i, j = 0;
|
||||
unsigned int tmp;
|
||||
RING_LOCALS;
|
||||
|
||||
BEGIN_LP_RING( I810_CTX_SETUP_SIZE );
|
||||
|
|
@ -557,12 +536,10 @@ static void i810EmitContextVerified( drm_device_t *dev,
|
|||
OUT_RING( code[I810_CTXREG_ST1] );
|
||||
|
||||
for ( i = 4 ; i < I810_CTX_SETUP_SIZE ; i++ ) {
|
||||
tmp = code[i];
|
||||
|
||||
if ((tmp & (7<<29)) == (3<<29) &&
|
||||
(tmp & (0x1f<<24)) < (0x1d<<24))
|
||||
if ((code[i] & (7<<29)) == (3<<29) &&
|
||||
(code[i] & (0x1f<<24)) < (0x1d<<24))
|
||||
{
|
||||
OUT_RING( tmp );
|
||||
OUT_RING( code[i] );
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
|
@ -578,7 +555,6 @@ static void i810EmitTexVerified( drm_device_t *dev,
|
|||
{
|
||||
drm_i810_private_t *dev_priv = dev->dev_private;
|
||||
int i, j = 0;
|
||||
unsigned int tmp;
|
||||
RING_LOCALS;
|
||||
|
||||
BEGIN_LP_RING( I810_TEX_SETUP_SIZE );
|
||||
|
|
@ -589,12 +565,11 @@ static void i810EmitTexVerified( drm_device_t *dev,
|
|||
OUT_RING( code[I810_TEXREG_MI3] );
|
||||
|
||||
for ( i = 4 ; i < I810_TEX_SETUP_SIZE ; i++ ) {
|
||||
tmp = code[i];
|
||||
|
||||
if ((tmp & (7<<29)) == (3<<29) &&
|
||||
(tmp & (0x1f<<24)) < (0x1d<<24))
|
||||
if ((code[i] & (7<<29)) == (3<<29) &&
|
||||
(code[i] & (0x1f<<24)) < (0x1d<<24))
|
||||
{
|
||||
OUT_RING( tmp );
|
||||
OUT_RING( code[i] );
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
|
@ -621,9 +596,7 @@ static void i810EmitDestVerified( drm_device_t *dev,
|
|||
if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) {
|
||||
OUT_RING( CMD_OP_DESTBUFFER_INFO );
|
||||
OUT_RING( tmp );
|
||||
} else
|
||||
DRM_DEBUG("bad di1 %x (allow %x or %x)\n",
|
||||
tmp, dev_priv->front_di1, dev_priv->back_di1);
|
||||
}
|
||||
|
||||
/* invarient:
|
||||
*/
|
||||
|
|
@ -645,30 +618,24 @@ static void i810EmitDestVerified( drm_device_t *dev,
|
|||
|
||||
|
||||
|
||||
static void i810EmitState( drm_device_t *dev )
|
||||
static void i810EmitState( drm_device_t *dev,
|
||||
drm_i810_state_t *state,
|
||||
unsigned int dirty )
|
||||
{
|
||||
drm_i810_private_t *dev_priv = dev->dev_private;
|
||||
drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
unsigned int dirty = sarea_priv->dirty;
|
||||
|
||||
if (dirty & I810_UPLOAD_BUFFERS) {
|
||||
i810EmitDestVerified( dev, sarea_priv->BufferState );
|
||||
sarea_priv->dirty &= ~I810_UPLOAD_BUFFERS;
|
||||
i810EmitDestVerified( dev, state->BufferSetup );
|
||||
}
|
||||
|
||||
if (dirty & I810_UPLOAD_CTX) {
|
||||
i810EmitContextVerified( dev, sarea_priv->ContextState );
|
||||
sarea_priv->dirty &= ~I810_UPLOAD_CTX;
|
||||
i810EmitContextVerified( dev, state->Setup );
|
||||
}
|
||||
|
||||
if (dirty & I810_UPLOAD_TEX0) {
|
||||
i810EmitTexVerified( dev, sarea_priv->TexState[0] );
|
||||
sarea_priv->dirty &= ~I810_UPLOAD_TEX0;
|
||||
i810EmitTexVerified( dev, state->TexSetup[0] );
|
||||
}
|
||||
|
||||
if (dirty & I810_UPLOAD_TEX1) {
|
||||
i810EmitTexVerified( dev, sarea_priv->TexState[1] );
|
||||
sarea_priv->dirty &= ~I810_UPLOAD_TEX1;
|
||||
i810EmitTexVerified( dev, state->TexSetup[1] );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -708,7 +675,6 @@ static void i810_dma_dispatch_clear( drm_device_t *dev, int flags,
|
|||
continue;
|
||||
|
||||
if ( flags & I810_FRONT ) {
|
||||
DRM_DEBUG("clear front\n");
|
||||
BEGIN_LP_RING( 6 );
|
||||
OUT_RING( BR00_BITBLT_CLIENT |
|
||||
BR00_OP_COLOR_BLT | 0x3 );
|
||||
|
|
@ -721,7 +687,6 @@ static void i810_dma_dispatch_clear( drm_device_t *dev, int flags,
|
|||
}
|
||||
|
||||
if ( flags & I810_BACK ) {
|
||||
DRM_DEBUG("clear back\n");
|
||||
BEGIN_LP_RING( 6 );
|
||||
OUT_RING( BR00_BITBLT_CLIENT |
|
||||
BR00_OP_COLOR_BLT | 0x3 );
|
||||
|
|
@ -734,7 +699,6 @@ static void i810_dma_dispatch_clear( drm_device_t *dev, int flags,
|
|||
}
|
||||
|
||||
if ( flags & I810_DEPTH ) {
|
||||
DRM_DEBUG("clear depth\n");
|
||||
BEGIN_LP_RING( 6 );
|
||||
OUT_RING( BR00_BITBLT_CLIENT |
|
||||
BR00_OP_COLOR_BLT | 0x3 );
|
||||
|
|
@ -760,8 +724,6 @@ static void i810_dma_dispatch_swap( drm_device_t *dev )
|
|||
int i;
|
||||
RING_LOCALS;
|
||||
|
||||
DRM_DEBUG("swapbuffers\n");
|
||||
|
||||
i810_kernel_lost_context(dev);
|
||||
|
||||
if (nbox > I810_NR_SAREA_CLIPRECTS)
|
||||
|
|
@ -780,10 +742,6 @@ static void i810_dma_dispatch_swap( drm_device_t *dev )
|
|||
pbox->y2 > dev_priv->h)
|
||||
continue;
|
||||
|
||||
DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n",
|
||||
pbox[i].x1, pbox[i].y1,
|
||||
pbox[i].x2, pbox[i].y2);
|
||||
|
||||
BEGIN_LP_RING( 6 );
|
||||
OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 );
|
||||
OUT_RING( pitch | (0xCC << 16));
|
||||
|
|
@ -799,7 +757,10 @@ static void i810_dma_dispatch_swap( drm_device_t *dev )
|
|||
static void i810_dma_dispatch_vertex(drm_device_t *dev,
|
||||
drm_buf_t *buf,
|
||||
int discard,
|
||||
int used)
|
||||
drm_i810_prim_t *prim,
|
||||
unsigned int nrprim,
|
||||
drm_i810_state_t *state,
|
||||
unsigned int nrstate )
|
||||
{
|
||||
drm_i810_private_t *dev_priv = dev->dev_private;
|
||||
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
|
||||
|
|
@ -807,139 +768,92 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev,
|
|||
drm_clip_rect_t *box = sarea_priv->boxes;
|
||||
int nbox = sarea_priv->nbox;
|
||||
unsigned long address = (unsigned long)buf->bus_address;
|
||||
unsigned long start = address - dev->agp->base;
|
||||
int i = 0, u;
|
||||
unsigned long bufstart = address - dev->agp->base;
|
||||
char *buf_virtual = (char *)buf_priv->virtual;
|
||||
unsigned int i;
|
||||
RING_LOCALS;
|
||||
|
||||
if (nbox > I810_NR_SAREA_CLIPRECTS)
|
||||
nrprim = 0;
|
||||
|
||||
i810_kernel_lost_context(dev);
|
||||
|
||||
if (nbox > I810_NR_SAREA_CLIPRECTS)
|
||||
nbox = I810_NR_SAREA_CLIPRECTS;
|
||||
for (i = 0 ; i < nrprim ; i++, prim++) {
|
||||
int j = 0;
|
||||
|
||||
if (discard) {
|
||||
u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
|
||||
I810_BUF_HARDWARE);
|
||||
if(u != I810_BUF_CLIENT) {
|
||||
DRM_DEBUG("xxxx 2\n");
|
||||
}
|
||||
}
|
||||
/* printk("prim %d start %x fin %x\n", i, prim->start, */
|
||||
/* prim->finish); */
|
||||
|
||||
if (used > 4*1024)
|
||||
used = 0;
|
||||
|
||||
if (sarea_priv->dirty)
|
||||
i810EmitState( dev );
|
||||
|
||||
DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n",
|
||||
address, used, nbox);
|
||||
|
||||
dev_priv->counter++;
|
||||
DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter);
|
||||
DRM_DEBUG( "i810_dma_dispatch\n");
|
||||
DRM_DEBUG( "start : %lx\n", start);
|
||||
DRM_DEBUG( "used : %d\n", used);
|
||||
DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4);
|
||||
|
||||
if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
|
||||
*(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE |
|
||||
sarea_priv->vertex_prim |
|
||||
((used/4)-2));
|
||||
|
||||
if (used & 4) {
|
||||
*(u32 *)((u32)buf_priv->virtual + used) = 0;
|
||||
used += 4;
|
||||
if ((unsigned)prim->start >= I810_DMA_BUF_SZ ||
|
||||
prim->start >= prim->finish ||
|
||||
(prim->start & 0x7) != 0x4) {
|
||||
/* printk("alignment/other\n"); */
|
||||
continue;
|
||||
}
|
||||
|
||||
i810_unmap_buffer(buf);
|
||||
}
|
||||
if (prim->dirty && prim->stateidx < nrstate) {
|
||||
i810EmitState( dev,
|
||||
&state[(int)prim->stateidx],
|
||||
prim->dirty );
|
||||
}
|
||||
|
||||
*(int *)&buf_virtual[prim->start-4] =
|
||||
(GFX_OP_PRIMITIVE | (((int)prim->prim) << 18) |
|
||||
((prim->finish - prim->start)/4-1));
|
||||
|
||||
|
||||
if (prim->finish & 0x4) {
|
||||
*(int *)&buf_virtual[prim->finish] = 0;
|
||||
prim->finish += 4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (used) {
|
||||
do {
|
||||
if (i < nbox) {
|
||||
if (j < nbox) {
|
||||
BEGIN_LP_RING(4);
|
||||
OUT_RING( GFX_OP_SCISSOR | SC_UPDATE_SCISSOR |
|
||||
OUT_RING( GFX_OP_SCISSOR |
|
||||
SC_UPDATE_SCISSOR |
|
||||
SC_ENABLE );
|
||||
OUT_RING( GFX_OP_SCISSOR_INFO );
|
||||
OUT_RING( box[i].x1 | (box[i].y1<<16) );
|
||||
OUT_RING( (box[i].x2-1) | ((box[i].y2-1)<<16) );
|
||||
OUT_RING( box[j].x1 | (box[j].y1<<16) );
|
||||
OUT_RING( (box[j].x2-1) | ((box[j].y2-1)<<16) );
|
||||
ADVANCE_LP_RING();
|
||||
if (nbox == 1) nbox = 0;
|
||||
}
|
||||
|
||||
BEGIN_LP_RING(4);
|
||||
OUT_RING( CMD_OP_BATCH_BUFFER );
|
||||
OUT_RING( start | BB1_PROTECTED );
|
||||
OUT_RING( start + used - 4 );
|
||||
OUT_RING( (bufstart + prim->start - 4) |
|
||||
BB1_PROTECTED );
|
||||
OUT_RING( (bufstart + prim->finish - 4) );
|
||||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
} while (++i < nbox);
|
||||
} while (++j < nbox);
|
||||
}
|
||||
|
||||
BEGIN_LP_RING(10);
|
||||
OUT_RING( CMD_STORE_DWORD_IDX );
|
||||
OUT_RING( 20 );
|
||||
OUT_RING( dev_priv->counter );
|
||||
OUT_RING( 0 );
|
||||
|
||||
if (discard) {
|
||||
dev_priv->counter++;
|
||||
|
||||
(void) cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
|
||||
I810_BUF_HARDWARE);
|
||||
|
||||
BEGIN_LP_RING( 8 );
|
||||
OUT_RING( CMD_STORE_DWORD_IDX );
|
||||
OUT_RING( 20 );
|
||||
OUT_RING( dev_priv->counter );
|
||||
OUT_RING( CMD_STORE_DWORD_IDX );
|
||||
OUT_RING( buf_priv->my_use_idx );
|
||||
OUT_RING( I810_BUF_FREE );
|
||||
OUT_RING( CMD_REPORT_HEAD );
|
||||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
||||
OUT_RING( CMD_REPORT_HEAD );
|
||||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
||||
|
||||
/* Interrupts are only for flushing */
|
||||
void i810_dma_service(int irq, void *device, struct pt_regs *regs)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)device;
|
||||
drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
|
||||
u16 temp;
|
||||
|
||||
atomic_inc(&dev->counts[_DRM_STAT_IRQ]);
|
||||
temp = I810_READ16(I810REG_INT_IDENTITY_R);
|
||||
temp = temp & ~(0x6000);
|
||||
if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R,
|
||||
temp); /* Clear all interrupts */
|
||||
else
|
||||
return;
|
||||
|
||||
queue_task(&dev->tq, &tq_immediate);
|
||||
mark_bh(IMMEDIATE_BH);
|
||||
}
|
||||
|
||||
void i810_dma_immediate_bh(void *device)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *) device;
|
||||
drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
|
||||
|
||||
atomic_set(&dev_priv->flush_done, 1);
|
||||
wake_up_interruptible(&dev_priv->flush_queue);
|
||||
}
|
||||
|
||||
static inline void i810_dma_emit_flush(drm_device_t *dev)
|
||||
{
|
||||
drm_i810_private_t *dev_priv = dev->dev_private;
|
||||
RING_LOCALS;
|
||||
|
||||
i810_kernel_lost_context(dev);
|
||||
|
||||
BEGIN_LP_RING(2);
|
||||
OUT_RING( CMD_REPORT_HEAD );
|
||||
OUT_RING( GFX_OP_USER_INTERRUPT );
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
/* i810_wait_ring( dev, dev_priv->ring.Size - 8 ); */
|
||||
/* atomic_set(&dev_priv->flush_done, 1); */
|
||||
/* wake_up_interruptible(&dev_priv->flush_queue); */
|
||||
}
|
||||
|
||||
static inline void i810_dma_quiescent_emit(drm_device_t *dev)
|
||||
void i810_dma_quiescent(drm_device_t *dev)
|
||||
{
|
||||
drm_i810_private_t *dev_priv = dev->dev_private;
|
||||
RING_LOCALS;
|
||||
|
|
@ -950,79 +864,27 @@ static inline void i810_dma_quiescent_emit(drm_device_t *dev)
|
|||
OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
|
||||
OUT_RING( CMD_REPORT_HEAD );
|
||||
OUT_RING( 0 );
|
||||
OUT_RING( GFX_OP_USER_INTERRUPT );
|
||||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
/* i810_wait_ring( dev, dev_priv->ring.Size - 8 ); */
|
||||
/* atomic_set(&dev_priv->flush_done, 1); */
|
||||
/* wake_up_interruptible(&dev_priv->flush_queue); */
|
||||
}
|
||||
|
||||
void i810_dma_quiescent(drm_device_t *dev)
|
||||
{
|
||||
DECLARE_WAITQUEUE(entry, current);
|
||||
drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
|
||||
unsigned long end;
|
||||
|
||||
if(dev_priv == NULL) {
|
||||
return;
|
||||
}
|
||||
atomic_set(&dev_priv->flush_done, 0);
|
||||
add_wait_queue(&dev_priv->flush_queue, &entry);
|
||||
end = jiffies + (HZ*3);
|
||||
|
||||
for (;;) {
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
i810_dma_quiescent_emit(dev);
|
||||
if (atomic_read(&dev_priv->flush_done) == 1) break;
|
||||
if((signed)(end - jiffies) <= 0) {
|
||||
DRM_ERROR("lockup\n");
|
||||
break;
|
||||
}
|
||||
schedule_timeout(HZ*3);
|
||||
if (signal_pending(current)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
current->state = TASK_RUNNING;
|
||||
remove_wait_queue(&dev_priv->flush_queue, &entry);
|
||||
|
||||
return;
|
||||
i810_wait_ring( dev, dev_priv->ring.Size - 8 );
|
||||
}
|
||||
|
||||
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;
|
||||
drm_i810_private_t *dev_priv = dev->dev_private;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
unsigned long end;
|
||||
int i, ret = 0;
|
||||
RING_LOCALS;
|
||||
|
||||
i810_kernel_lost_context(dev);
|
||||
|
||||
if(dev_priv == NULL) {
|
||||
return 0;
|
||||
}
|
||||
atomic_set(&dev_priv->flush_done, 0);
|
||||
add_wait_queue(&dev_priv->flush_queue, &entry);
|
||||
end = jiffies + (HZ*3);
|
||||
for (;;) {
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
i810_dma_emit_flush(dev);
|
||||
if (atomic_read(&dev_priv->flush_done) == 1) break;
|
||||
if((signed)(end - jiffies) <= 0) {
|
||||
DRM_ERROR("lockup\n");
|
||||
break;
|
||||
}
|
||||
schedule_timeout(HZ*3);
|
||||
if (signal_pending(current)) {
|
||||
ret = -EINTR; /* Can't restart */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
current->state = TASK_RUNNING;
|
||||
remove_wait_queue(&dev_priv->flush_queue, &entry);
|
||||
BEGIN_LP_RING(2);
|
||||
OUT_RING( CMD_REPORT_HEAD );
|
||||
OUT_RING( 0 );
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
i810_wait_ring( dev, dev_priv->ring.Size - 8 );
|
||||
|
||||
for (i = 0; i < dma->buf_count; i++) {
|
||||
drm_buf_t *buf = dma->buflist[ i ];
|
||||
|
|
@ -1034,7 +896,7 @@ static int i810_flush_queue(drm_device_t *dev)
|
|||
if (used == I810_BUF_HARDWARE)
|
||||
DRM_DEBUG("reclaimed from HARDWARE\n");
|
||||
if (used == I810_BUF_CLIENT)
|
||||
DRM_DEBUG("still on client HARDWARE\n");
|
||||
DRM_DEBUG("still on client\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -1074,7 +936,6 @@ int i810_flush_ioctl(struct inode *inode, struct file *filp,
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
|
||||
DRM_DEBUG("i810_flush_ioctl\n");
|
||||
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
||||
DRM_ERROR("i810_flush_ioctl called without lock held\n");
|
||||
return -EINVAL;
|
||||
|
|
@ -1085,8 +946,32 @@ int i810_flush_ioctl(struct inode *inode, struct file *filp,
|
|||
}
|
||||
|
||||
|
||||
/* Copy sarea data into temporary structs.
|
||||
*/
|
||||
void i810_copy_state( drm_i810_sarea_t *sarea, drm_i810_state_t *state )
|
||||
{
|
||||
if (sarea->dirty & I810_UPLOAD_CTX)
|
||||
memcpy(state->Setup, sarea->ContextState,
|
||||
sizeof(state->Setup));
|
||||
|
||||
if (sarea->dirty & I810_UPLOAD_BUFFERS)
|
||||
memcpy(state->BufferSetup, sarea->BufferState,
|
||||
sizeof(state->BufferSetup));
|
||||
|
||||
if (sarea->dirty & I810_UPLOAD_TEX0)
|
||||
memcpy(state->TexSetup[0], sarea->TexState[0],
|
||||
sizeof(state->TexSetup[0]));
|
||||
|
||||
if (sarea->dirty & I810_UPLOAD_TEX1)
|
||||
memcpy(state->TexSetup[1], sarea->TexState[1],
|
||||
sizeof(state->TexSetup[1]));
|
||||
}
|
||||
|
||||
|
||||
/* Obsolete, backwards compatibility ioctl:
|
||||
*/
|
||||
int i810_dma_vertex(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;
|
||||
|
|
@ -1096,6 +981,12 @@ int i810_dma_vertex(struct inode *inode, struct file *filp,
|
|||
drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
|
||||
dev_priv->sarea_priv;
|
||||
drm_i810_vertex_t vertex;
|
||||
drm_buf_t *buf;
|
||||
drm_i810_buf_priv_t *buf_priv;
|
||||
drm_i810_state_t tmpstate;
|
||||
drm_i810_prim_t tmpprim;
|
||||
|
||||
/* printk("%s\n", __FUNCTION__); */
|
||||
|
||||
if (copy_from_user(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex)))
|
||||
return -EFAULT;
|
||||
|
|
@ -1105,24 +996,116 @@ int i810_dma_vertex(struct inode *inode, struct file *filp,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n",
|
||||
vertex.idx, vertex.used, vertex.discard);
|
||||
buf = dma->buflist[ vertex.idx ];
|
||||
buf_priv = buf->dev_private;
|
||||
|
||||
if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL;
|
||||
if (vertex.idx < 0 || vertex.idx >= I810_DMA_BUF_NR) {
|
||||
DRM_ERROR("i810_dma_vertex2 bad buffer idx\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (sarea_priv->dirty)
|
||||
i810_copy_state( sarea_priv, &tmpstate );
|
||||
|
||||
i810_dma_dispatch_vertex( dev,
|
||||
dma->buflist[ vertex.idx ],
|
||||
vertex.discard, vertex.used );
|
||||
tmpprim.start = 0;
|
||||
tmpprim.finish = vertex.used;
|
||||
tmpprim.prim = (char) sarea_priv->vertex_prim;
|
||||
tmpprim.dirty = (char) sarea_priv->dirty;
|
||||
tmpprim.stateidx = 0;
|
||||
|
||||
i810_dma_dispatch_vertex( dev, buf,
|
||||
vertex.discard,
|
||||
&tmpprim, 1,
|
||||
&tmpstate, 1 );
|
||||
|
||||
if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
|
||||
i810_unmap_buffer(buf);
|
||||
}
|
||||
|
||||
atomic_add(vertex.used, &dev->counts[_DRM_STAT_SECONDARY]);
|
||||
atomic_inc(&dev->counts[_DRM_STAT_DMA]);
|
||||
|
||||
sarea_priv->last_enqueue = dev_priv->counter-1;
|
||||
sarea_priv->last_dispatch = (int) hw_status[5];
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int i810_dma_vertex2(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_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
|
||||
u32 *hw_status = (u32 *)dev_priv->hw_status_page;
|
||||
drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
|
||||
dev_priv->sarea_priv;
|
||||
drm_i810_vertex2_t vertex;
|
||||
drm_buf_t *buf;
|
||||
drm_i810_buf_priv_t *buf_priv;
|
||||
|
||||
/* printk("%s\n", __FUNCTION__); */
|
||||
|
||||
if (copy_from_user(&vertex, (drm_i810_vertex2_t *)arg, sizeof(vertex)))
|
||||
return -EFAULT;
|
||||
|
||||
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
||||
DRM_ERROR("i810_dma_vertex2 called without lock held\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (vertex.idx >= I810_DMA_BUF_NR) {
|
||||
DRM_ERROR("i810_dma_vertex2 bad buffer idx\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
/* printk("%s buf %d nstates %d nprim %d\n", */
|
||||
/* __FUNCTION__, */
|
||||
/* vertex.idx, */
|
||||
/* vertex.nr_states, */
|
||||
/* vertex.nr_prims ); */
|
||||
|
||||
buf = dma->buflist[ vertex.idx ];
|
||||
buf_priv = buf->dev_private;
|
||||
|
||||
if (vertex.nr_states) {
|
||||
if (vertex.nr_states >= I810_MAX_STATES)
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(dev_priv->statetmp,
|
||||
vertex.state_address,
|
||||
vertex.nr_states * sizeof(drm_i810_state_t)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (vertex.nr_prims) {
|
||||
if (vertex.nr_prims >= I810_MAX_PRIMS)
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(dev_priv->primtmp,
|
||||
vertex.prim_address,
|
||||
vertex.nr_prims * sizeof(drm_i810_prim_t)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
i810_dma_dispatch_vertex( dev, buf,
|
||||
vertex.discard,
|
||||
dev_priv->primtmp,
|
||||
vertex.nr_prims,
|
||||
dev_priv->statetmp,
|
||||
vertex.nr_states );
|
||||
|
||||
if (buf_priv->currently_mapped == I810_BUF_MAPPED)
|
||||
i810_unmap_buffer(buf);
|
||||
|
||||
atomic_inc(&dev->counts[_DRM_STAT_DMA]);
|
||||
|
||||
sarea_priv->last_enqueue = dev_priv->counter-1;
|
||||
sarea_priv->last_dispatch = (int) hw_status[5];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int i810_clear_bufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
|
|
@ -1156,8 +1139,6 @@ int i810_swap_bufs(struct inode *inode, struct file *filp,
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
|
||||
DRM_DEBUG("i810_swap_bufs\n");
|
||||
|
||||
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
||||
DRM_ERROR("i810_swap_buf called without lock held\n");
|
||||
return -EINVAL;
|
||||
|
|
@ -1193,7 +1174,6 @@ int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
|
||||
dev_priv->sarea_priv;
|
||||
|
||||
DRM_DEBUG("getbuf\n");
|
||||
if (copy_from_user(&d, (drm_i810_dma_t *)arg, sizeof(d)))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
@ -1206,9 +1186,6 @@ int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
|
||||
retcode = i810_dma_get_buffer(dev, &d, filp);
|
||||
|
||||
DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n",
|
||||
current->pid, retcode, d.granted);
|
||||
|
||||
if (copy_to_user((drm_dma_t *)arg, &d, sizeof(d)))
|
||||
return -EFAULT;
|
||||
sarea_priv->last_dispatch = (int) hw_status[5];
|
||||
|
|
@ -1216,46 +1193,18 @@ int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
return retcode;
|
||||
}
|
||||
|
||||
int i810_copybuf(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
int i810_copybuf(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_i810_copy_t d;
|
||||
drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
|
||||
u32 *hw_status = (u32 *)dev_priv->hw_status_page;
|
||||
drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
|
||||
dev_priv->sarea_priv;
|
||||
drm_buf_t *buf;
|
||||
drm_i810_buf_priv_t *buf_priv;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
|
||||
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
||||
DRM_ERROR("i810_dma called without lock held\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (copy_from_user(&d, (drm_i810_copy_t *)arg, sizeof(d)))
|
||||
return -EFAULT;
|
||||
|
||||
if(d.idx < 0 || d.idx > dma->buf_count) return -EINVAL;
|
||||
buf = dma->buflist[ d.idx ];
|
||||
buf_priv = buf->dev_private;
|
||||
if (buf_priv->currently_mapped != I810_BUF_MAPPED) return -EPERM;
|
||||
|
||||
if(d.used < 0 || d.used > buf->total) return -EINVAL;
|
||||
|
||||
if (copy_from_user(buf_priv->virtual, d.address, d.used))
|
||||
return -EFAULT;
|
||||
|
||||
sarea_priv->last_dispatch = (int) hw_status[5];
|
||||
|
||||
/* Never copy - 2.4.x doesn't need it */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i810_docopy(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
if(VM_DONTCOPY == 0) return 1;
|
||||
/* Never copy - 2.4.x doesn't need it */
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,6 +88,8 @@
|
|||
#define I810_TEXREG_MCS 7 /* GFX_OP_MAP_COORD_SETS ??? */
|
||||
#define I810_TEX_SETUP_SIZE 8
|
||||
|
||||
/* Flags for clear ioctl
|
||||
*/
|
||||
#define I810_FRONT 0x1
|
||||
#define I810_BACK 0x2
|
||||
#define I810_DEPTH 0x4
|
||||
|
|
@ -189,6 +191,52 @@ typedef struct _drm_i810_copy_t {
|
|||
void *address; /* Address to copy from */
|
||||
} drm_i810_copy_t;
|
||||
|
||||
|
||||
typedef struct _drm_i810_state {
|
||||
unsigned int Setup[I810_CTX_SETUP_SIZE];
|
||||
unsigned int BufferSetup[I810_DEST_SETUP_SIZE];
|
||||
unsigned int TexSetup[2][I810_TEX_SETUP_SIZE];
|
||||
} drm_i810_state_t;
|
||||
|
||||
#define PR_TRIANGLES (0x0)
|
||||
#define PR_TRISTRIP_0 (0x1)
|
||||
#define PR_TRISTRIP_1 (0x2)
|
||||
#define PR_TRIFAN (0x3)
|
||||
#define PR_POLYGON (0x4)
|
||||
#define PR_LINES (0x5)
|
||||
#define PR_LINESTRIP (0x6)
|
||||
#define PR_RECTS (0x7)
|
||||
|
||||
typedef struct _drm_i810_prim {
|
||||
int start;
|
||||
int finish;
|
||||
char prim;
|
||||
char dirty;
|
||||
char stateidx;
|
||||
} drm_i810_prim_t;
|
||||
|
||||
|
||||
#define I810_MAX_PRIMS 100
|
||||
#define I810_MAX_STATES 20
|
||||
|
||||
/* Still uses the sarea to pass cliprects (fix?). State and primitive
|
||||
* information are passed directly as pointers to userspace data.
|
||||
* Copying of vertex data is performed by this ioctl as well.
|
||||
*
|
||||
* This obsoletes _drm_i810_vertex, _drm_i810_copy and the state and
|
||||
* primitive fields in the sarea.
|
||||
*/
|
||||
typedef struct _drm_i810_vertex2 {
|
||||
unsigned int idx; /* buffer index */
|
||||
unsigned int discard; /* client is finished with the buffer? */
|
||||
void *vertex_address;
|
||||
unsigned int nr_states;
|
||||
drm_i810_state_t *state_address;
|
||||
unsigned int nr_prims;
|
||||
drm_i810_prim_t *prim_address;
|
||||
} drm_i810_vertex2_t;
|
||||
|
||||
|
||||
typedef struct drm_i810_dma {
|
||||
void *virtual;
|
||||
int request_idx;
|
||||
|
|
|
|||
|
|
@ -54,7 +54,8 @@
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)] = { i810_swap_bufs, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)] = { i810_copybuf, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX2)] = { i810_dma_vertex2, 1, 0 },
|
||||
|
||||
|
||||
#define __HAVE_COUNTERS 4
|
||||
|
|
|
|||
|
|
@ -64,8 +64,6 @@ typedef struct drm_i810_private {
|
|||
unsigned long hw_status_page;
|
||||
unsigned long counter;
|
||||
|
||||
atomic_t flush_done;
|
||||
wait_queue_head_t flush_queue; /* Processes waiting until flush */
|
||||
drm_buf_t *mmap_buffer;
|
||||
|
||||
|
||||
|
|
@ -75,6 +73,12 @@ typedef struct drm_i810_private {
|
|||
int depth_offset;
|
||||
int w, h;
|
||||
int pitch;
|
||||
|
||||
/* Temporaries to hold userspace data before submitting to the
|
||||
* ring.
|
||||
*/
|
||||
drm_i810_state_t statetmp[I810_MAX_STATES];
|
||||
drm_i810_prim_t primtmp[I810_MAX_STATES];
|
||||
} drm_i810_private_t;
|
||||
|
||||
/* i810_dma.c */
|
||||
|
|
@ -89,19 +93,29 @@ extern void i810_reclaim_buffers(drm_device_t *dev, pid_t pid);
|
|||
extern int i810_getage(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma);
|
||||
|
||||
/* Obsolete:
|
||||
*/
|
||||
extern int i810_copybuf(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
/* Obsolete:
|
||||
*/
|
||||
extern int i810_docopy(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
extern void i810_dma_quiescent(drm_device_t *dev);
|
||||
|
||||
#define I810_VERBOSE 0
|
||||
|
||||
|
||||
/* Obsolete
|
||||
*/
|
||||
int i810_dma_vertex(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
/* Handles multiple prims/ioctl, does any necessary copying in this
|
||||
* ioctl:
|
||||
*/
|
||||
int i810_dma_vertex2(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
int i810_swap_bufs(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
* Authors:
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
* Keith Whitwell <keith_whitwell@yahoo.com>
|
||||
*/
|
||||
|
||||
#ifndef __RADEON_DRM_H__
|
||||
|
|
@ -46,7 +47,6 @@
|
|||
#define RADEON_UPLOAD_MASKS 0x00000010
|
||||
#define RADEON_UPLOAD_VIEWPORT 0x00000020
|
||||
#define RADEON_UPLOAD_SETUP 0x00000040
|
||||
#define RADEON_UPLOAD_TCL 0x00000080
|
||||
#define RADEON_UPLOAD_MISC 0x00000100
|
||||
#define RADEON_UPLOAD_TEX0 0x00000200
|
||||
#define RADEON_UPLOAD_TEX1 0x00000400
|
||||
|
|
@ -82,8 +82,6 @@
|
|||
|
||||
#define RADEON_SCRATCH_REG_OFFSET 32
|
||||
|
||||
/* Keep these small for testing
|
||||
*/
|
||||
#define RADEON_NR_SAREA_CLIPRECTS 12
|
||||
|
||||
/* There are 2 heaps (local/AGP). Each region within a heap is a
|
||||
|
|
@ -202,8 +200,9 @@ typedef struct {
|
|||
} drm_radeon_tex_region_t;
|
||||
|
||||
typedef struct {
|
||||
/* The channel for communication of state information to the kernel
|
||||
* on firing a vertex buffer.
|
||||
/* The channel for communication of state information to the
|
||||
* kernel on firing a vertex buffer with either of the
|
||||
* obsoleted vertex/index ioctls.
|
||||
*/
|
||||
drm_radeon_context_regs_t context_state;
|
||||
drm_radeon_texture_regs_t tex_state[RADEON_MAX_TEXTURE_UNITS];
|
||||
|
|
@ -296,6 +295,15 @@ typedef struct drm_radeon_vertex {
|
|||
int discard; /* Client finished with buffer? */
|
||||
} drm_radeon_vertex_t;
|
||||
|
||||
typedef struct drm_radeon_vertex {
|
||||
int idx; /* Index of vertex buffer */
|
||||
int discard; /* Client finished with buffer? */
|
||||
int nr_states;
|
||||
drm_radeon_state_t *state;
|
||||
int nr_prims;
|
||||
drm_radeon_prim_t *prim;
|
||||
} drm_radeon_vertex2_t;
|
||||
|
||||
typedef struct drm_radeon_indices {
|
||||
int prim;
|
||||
int idx;
|
||||
|
|
@ -319,6 +327,16 @@ typedef struct drm_radeon_texture {
|
|||
drm_radeon_tex_image_t *image;
|
||||
} drm_radeon_texture_t;
|
||||
|
||||
typedef struct drm_radeon_texture2 {
|
||||
int offset;
|
||||
int pitch;
|
||||
int format;
|
||||
int width; /* Texture image coordinates */
|
||||
int height;
|
||||
drm_radeon_tex_image_t blit;
|
||||
const void *data;
|
||||
} drm_radeon_texture2_t;
|
||||
|
||||
typedef struct drm_radeon_stipple {
|
||||
unsigned int *mask;
|
||||
} drm_radeon_stipple_t;
|
||||
|
|
|
|||
|
|
@ -104,6 +104,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
|
||||
|
|
@ -449,6 +450,7 @@ typedef struct drm_scatter_gather {
|
|||
#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46)
|
||||
#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
|
||||
#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48)
|
||||
#define DRM_IOCTL_I810_VERTEX2 DRM_IOW( 0x49, drm_i810_vertex2_t)
|
||||
|
||||
/* Rage 128 specific ioctls */
|
||||
#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
|
||||
|
|
@ -466,6 +468,7 @@ typedef struct drm_scatter_gather {
|
|||
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
|
||||
#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
|
||||
#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t)
|
||||
#define DRM_IOCTL_R128_CLEAR2 DRM_IOW( 0x51, drm_r128_clear2_t)
|
||||
|
||||
/* Radeon specific ioctls */
|
||||
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t)
|
||||
|
|
@ -483,6 +486,10 @@ typedef struct drm_scatter_gather {
|
|||
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
|
||||
#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t)
|
||||
|
||||
/* Gamma specific ioctls */
|
||||
#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t)
|
||||
#define DRM_IOCTL_GAMMA_COPY DRM_IOW( 0x41, drm_gamma_copy_t)
|
||||
|
||||
#ifdef CONFIG_DRM_SIS
|
||||
/* SiS specific ioctls */
|
||||
#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t)
|
||||
|
|
|
|||
|
|
@ -104,6 +104,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
|
||||
|
|
@ -449,6 +450,7 @@ typedef struct drm_scatter_gather {
|
|||
#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46)
|
||||
#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
|
||||
#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48)
|
||||
#define DRM_IOCTL_I810_VERTEX2 DRM_IOW( 0x49, drm_i810_vertex2_t)
|
||||
|
||||
/* Rage 128 specific ioctls */
|
||||
#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t)
|
||||
|
|
@ -466,6 +468,7 @@ typedef struct drm_scatter_gather {
|
|||
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
|
||||
#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
|
||||
#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t)
|
||||
#define DRM_IOCTL_R128_CLEAR2 DRM_IOW( 0x51, drm_r128_clear2_t)
|
||||
|
||||
/* Radeon specific ioctls */
|
||||
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t)
|
||||
|
|
@ -483,6 +486,10 @@ typedef struct drm_scatter_gather {
|
|||
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
|
||||
#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t)
|
||||
|
||||
/* Gamma specific ioctls */
|
||||
#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t)
|
||||
#define DRM_IOCTL_GAMMA_COPY DRM_IOW( 0x41, drm_gamma_copy_t)
|
||||
|
||||
#ifdef CONFIG_DRM_SIS
|
||||
/* SiS specific ioctls */
|
||||
#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue