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; }
/* 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(); }
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(); }
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(); }
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; }
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; }
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; }