Esempio n. 1
0
static int mga_dma_indices(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
	drm_mga_private_t *dev_priv = dev->dev_private;
	struct drm_device_dma *dma = dev->dma;
	struct drm_buf *buf;
	drm_mga_buf_priv_t *buf_priv;
	drm_mga_indices_t *indices = data;

	LOCK_TEST_WITH_RETURN(dev, file_priv);

	if (indices->idx < 0 || indices->idx > dma->buf_count)
		return -EINVAL;

	buf = dma->buflist[indices->idx];
	buf_priv = buf->dev_private;

	buf_priv->discard = indices->discard;

	if (!mga_verify_state(dev_priv)) {
		if (indices->discard) {
			if (buf_priv->dispatched == 1)
				AGE_BUFFER(buf_priv);
			buf_priv->dispatched = 0;
			mga_freelist_put(dev, buf);
		}
		return -EINVAL;
	}

	WRAP_TEST_WITH_RETURN(dev_priv);

	mga_dma_dispatch_indices(dev, buf, indices->start, indices->end);

	return 0;
}
Esempio n. 2
0
/* This copies a 64 byte aligned agp region to the frambuffer with a
 * standard blit, the ioctl needs to do checking.
 */
static void mga_dma_dispatch_iload( drm_device_t *dev, drm_buf_t *buf,
                                    unsigned int dstorg, unsigned int length )
{
    drm_mga_private_t *dev_priv = dev->dev_private;
    drm_mga_buf_priv_t *buf_priv = buf->dev_private;
    drm_mga_context_regs_t *ctx = &dev_priv->sarea_priv->context_state;
    u32 srcorg = buf->bus_address | MGA_SRCACC_AGP | MGA_SRCMAP_SYSMEM;
    u32 y2;
    DMA_LOCALS;
    DRM_DEBUG( "%s: buf=%d used=%d\n",
               __FUNCTION__, buf->idx, buf->used );

    y2 = length / 64;

    BEGIN_DMA( 5 );

    DMA_BLOCK( MGA_DMAPAD,	0x00000000,
               MGA_DMAPAD,	0x00000000,
               MGA_DWGSYNC,	0x00007100,
               MGA_DWGSYNC,	0x00007000 );

    DMA_BLOCK( MGA_DSTORG,	dstorg,
               MGA_MACCESS,	0x00000000,
               MGA_SRCORG,	srcorg,
               MGA_AR5,	64 );

    DMA_BLOCK( MGA_PITCH,	64,
               MGA_PLNWT,	0xffffffff,
               MGA_DMAPAD,	0x00000000,
               MGA_DWGCTL,	MGA_DWGCTL_COPY );

    DMA_BLOCK( MGA_AR0,	63,
               MGA_AR3,	0,
               MGA_FXBNDRY,	(63 << 16) | 0,
               MGA_YDSTLEN + MGA_EXEC, y2 );

    DMA_BLOCK( MGA_PLNWT,	ctx->plnwt,
               MGA_SRCORG,	dev_priv->front_offset,
               MGA_PITCH,	dev_priv->front_pitch,
               MGA_DWGSYNC,	0x00007000 );

    ADVANCE_DMA();

    AGE_BUFFER( buf_priv );

    buf->pending = 0;
    buf->used = 0;
    buf_priv->dispatched = 0;

    mga_freelist_put( dev, buf );

    FLUSH_DMA();
}
Esempio n. 3
0
static void mga_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf )
{
	drm_mga_private_t *dev_priv = dev->dev_private;
	drm_mga_buf_priv_t *buf_priv = buf->dev_private;
	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
	u32 address = (u32) buf->bus_address;
	u32 length = (u32) buf->used;
	int i = 0;
	DMA_LOCALS;
	DRM_DEBUG( "vertex: buf=%d used=%d\n", buf->idx, buf->used );

	if ( buf->used ) {
		buf_priv->dispatched = 1;

		MGA_EMIT_STATE( dev_priv, sarea_priv->dirty );

		do {
			if ( i < sarea_priv->nbox ) {
				mga_emit_clip_rect( dev_priv,
						    &sarea_priv->boxes[i] );
			}

			BEGIN_DMA( 1 );

			DMA_BLOCK(MGA_DMAPAD, 0x00000000,
				  MGA_DMAPAD, 0x00000000,
				  MGA_SECADDRESS, (address |
						   MGA_DMA_VERTEX),
				  MGA_SECEND, ((address + length) |
					       dev_priv->dma_access));

			ADVANCE_DMA();
		} while ( ++i < sarea_priv->nbox );
	}

	if ( buf_priv->discard ) {
		AGE_BUFFER( buf_priv );
		buf->pending = 0;
		buf->used = 0;
		buf_priv->dispatched = 0;

		mga_freelist_put( dev, buf );
	}

	FLUSH_DMA();
}
Esempio n. 4
0
static void mga_dma_dispatch_indices( drm_device_t *dev, drm_buf_t *buf,
				      unsigned int start, unsigned int end )
{
	drm_mga_private_t *dev_priv = dev->dev_private;
	drm_mga_buf_priv_t *buf_priv = buf->dev_private;
	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
	u32 address = (u32) buf->bus_address;
	int i = 0;
	DMA_LOCALS;
	DRM_DEBUG( "indices: buf=%d start=%d end=%d\n", buf->idx, start, end );

	if ( start != end ) {
		buf_priv->dispatched = 1;

		MGA_EMIT_STATE( dev_priv, sarea_priv->dirty );

		do {
			if ( i < sarea_priv->nbox ) {
				mga_emit_clip_rect( dev_priv,
						    &sarea_priv->boxes[i] );
			}

			BEGIN_DMA( 1 );

			DMA_BLOCK(MGA_DMAPAD, 0x00000000,
				  MGA_DMAPAD, 0x00000000,
				  MGA_SETUPADDRESS, address + start,
				  MGA_SETUPEND, ((address + end) |
						 dev_priv->dma_access));

			ADVANCE_DMA();
		} while ( ++i < sarea_priv->nbox );
	}

	if ( buf_priv->discard ) {
		AGE_BUFFER( buf_priv );
		buf->pending = 0;
		buf->used = 0;
		buf_priv->dispatched = 0;

		mga_freelist_put( dev, buf );
	}

	FLUSH_DMA();
}
Esempio n. 5
0
int mga_dma_indices( 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_mga_private_t *dev_priv = dev->dev_private;
    drm_device_dma_t *dma = dev->dma;
    drm_buf_t *buf;
    drm_mga_buf_priv_t *buf_priv;
    drm_mga_indices_t indices;

    LOCK_TEST_WITH_RETURN( dev );

    if ( copy_from_user( &indices,
                         (drm_mga_indices_t *)arg,
                         sizeof(indices) ) )
        return -EFAULT;

    if(indices.idx < 0 || indices.idx > dma->buf_count) return -EINVAL;

    buf = dma->buflist[indices.idx];
    buf_priv = buf->dev_private;

    buf_priv->discard = indices.discard;

    if ( !mga_verify_state( dev_priv ) ) {
        if ( indices.discard ) {
            if ( buf_priv->dispatched == 1 )
                AGE_BUFFER( buf_priv );
            buf_priv->dispatched = 0;
            mga_freelist_put( dev, buf );
        }
        return -EINVAL;
    }

    WRAP_TEST_WITH_RETURN( dev_priv );

    mga_dma_dispatch_indices( dev, buf, indices.start, indices.end );

    return 0;
}
Esempio n. 6
0
static int mga_dma_indices(DRM_IOCTL_ARGS)
{
	DRM_DEVICE;
	drm_mga_private_t *dev_priv = dev->dev_private;
	struct drm_device_dma *dma = dev->dma;
	struct drm_buf *buf;
	drm_mga_buf_priv_t *buf_priv;
	drm_mga_indices_t indices;

	LOCK_TEST_WITH_RETURN(dev, filp);

	DRM_COPY_FROM_USER_IOCTL(indices,
				 (drm_mga_indices_t __user *) data,
				 sizeof(indices));

	if (indices.idx < 0 || indices.idx > dma->buf_count)
		return DRM_ERR(EINVAL);

	buf = dma->buflist[indices.idx];
	buf_priv = buf->dev_private;

	buf_priv->discard = indices.discard;

	if (!mga_verify_state(dev_priv)) {
		if (indices.discard) {
			if (buf_priv->dispatched == 1)
				AGE_BUFFER(buf_priv);
			buf_priv->dispatched = 0;
			mga_freelist_put(dev, buf);
		}
		return DRM_ERR(EINVAL);
	}

	WRAP_TEST_WITH_RETURN(dev_priv);

	mga_dma_dispatch_indices(dev, buf, indices.start, indices.end);

	return 0;
}
Esempio n. 7
0
int mga_dma_vertex(DRM_IOCTL_ARGS)
{
	DRM_DEVICE;
	drm_mga_private_t *dev_priv = dev->dev_private;
	drm_device_dma_t *dma = dev->dma;
	drm_buf_t *buf;
	drm_mga_buf_priv_t *buf_priv;
	drm_mga_vertex_t vertex;

	LOCK_TEST_WITH_RETURN(dev, filp);

	DRM_COPY_FROM_USER_IOCTL(vertex,
				 (drm_mga_vertex_t __user *) data,
				 sizeof(vertex));

	if (vertex.idx < 0 || vertex.idx > dma->buf_count)
		return DRM_ERR(EINVAL);
	buf = dma->buflist[vertex.idx];
	buf_priv = buf->dev_private;

	buf->used = vertex.used;
	buf_priv->discard = vertex.discard;

	if (!mga_verify_state(dev_priv)) {
		if (vertex.discard) {
			if (buf_priv->dispatched == 1)
				AGE_BUFFER(buf_priv);
			buf_priv->dispatched = 0;
			mga_freelist_put(dev, buf);
		}
		return DRM_ERR(EINVAL);
	}

	WRAP_TEST_WITH_RETURN(dev_priv);

	mga_dma_dispatch_vertex(dev, buf);

	return 0;
}