📄 mga_state.c
字号:
DMA_BLOCK( MGA_DMAPAD, 0x00000000, MGA_FCOL, clear->clear_color, MGA_DSTORG, dev_priv->front_offset, MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd ); ADVANCE_DMA(); } if ( clear->flags & MGA_BACK ) { BEGIN_DMA( 2 ); DMA_BLOCK( MGA_DMAPAD, 0x00000000, MGA_PLNWT, clear->color_mask, MGA_YDSTLEN, (box->y1 << 16) | height, MGA_FXBNDRY, (box->x2 << 16) | box->x1 ); DMA_BLOCK( MGA_DMAPAD, 0x00000000, MGA_FCOL, clear->clear_color, MGA_DSTORG, dev_priv->back_offset, MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd ); ADVANCE_DMA(); } if ( clear->flags & MGA_DEPTH ) { BEGIN_DMA( 2 ); DMA_BLOCK( MGA_DMAPAD, 0x00000000, MGA_PLNWT, clear->depth_mask, MGA_YDSTLEN, (box->y1 << 16) | height, MGA_FXBNDRY, (box->x2 << 16) | box->x1 ); DMA_BLOCK( MGA_DMAPAD, 0x00000000, MGA_FCOL, clear->clear_depth, MGA_DSTORG, dev_priv->depth_offset, MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd ); ADVANCE_DMA(); } } BEGIN_DMA( 1 ); /* Force reset of DWGCTL */ DMA_BLOCK( MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000, MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl ); ADVANCE_DMA(); FLUSH_DMA();}static void mga_dma_dispatch_swap( drm_device_t *dev ){ drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_context_regs_t *ctx = &sarea_priv->context_state; drm_clip_rect_t *pbox = sarea_priv->boxes; int nbox = sarea_priv->nbox; int i; DMA_LOCALS; DRM_DEBUG( "\n" ); sarea_priv->last_frame.head = dev_priv->prim.tail; sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap; BEGIN_DMA( 4 + nbox ); DMA_BLOCK( MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000, MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000 ); DMA_BLOCK( MGA_DSTORG, dev_priv->front_offset, MGA_MACCESS, dev_priv->maccess, MGA_SRCORG, dev_priv->back_offset, MGA_AR5, dev_priv->front_pitch ); DMA_BLOCK( MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000, MGA_PLNWT, 0xffffffff, MGA_DWGCTL, MGA_DWGCTL_COPY ); for ( i = 0 ; i < nbox ; i++ ) { drm_clip_rect_t *box = &pbox[i]; u32 height = box->y2 - box->y1; u32 start = box->y1 * dev_priv->front_pitch; DRM_DEBUG( " from=%d,%d to=%d,%d\n", box->x1, box->y1, box->x2, box->y2 ); DMA_BLOCK( MGA_AR0, start + box->x2 - 1, MGA_AR3, start + box->x1, MGA_FXBNDRY, ((box->x2 - 1) << 16) | box->x1, MGA_YDSTLEN + MGA_EXEC, (box->y1 << 16) | height ); } DMA_BLOCK( MGA_DMAPAD, 0x00000000, MGA_PLNWT, ctx->plnwt, MGA_SRCORG, dev_priv->front_offset, MGA_DWGCTL, ctx->dwgctl ); ADVANCE_DMA(); FLUSH_DMA(); DRM_DEBUG( "%s... done.\n", __FUNCTION__ );}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) | MGA_PAGPXFER) ); 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) | MGA_PAGPXFER) ); 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();}/* 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( "buf=%d used=%d\n", 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_blit( drm_device_t *dev, drm_mga_blit_t *blit ){ drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_context_regs_t *ctx = &sarea_priv->context_state; drm_clip_rect_t *pbox = sarea_priv->boxes; int nbox = sarea_priv->nbox; u32 scandir = 0, i; DMA_LOCALS; DRM_DEBUG( "\n" ); BEGIN_DMA( 4 + nbox ); DMA_BLOCK( MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000, MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000 ); DMA_BLOCK( MGA_DWGCTL, MGA_DWGCTL_COPY, MGA_PLNWT, blit->planemask, MGA_SRCORG, blit->srcorg, MGA_DSTORG, blit->dstorg ); DMA_BLOCK( MGA_SGN, scandir, MGA_MACCESS, dev_priv->maccess, MGA_AR5, blit->ydir * blit->src_pitch, MGA_PITCH, blit->dst_pitch ); for ( i = 0 ; i < nbox ; i++ ) { int srcx = pbox[i].x1 + blit->delta_sx; int srcy = pbox[i].y1 + blit->delta_sy; int dstx = pbox[i].x1 + blit->delta_dx; int dsty = pbox[i].y1 + blit->delta_dy; int h = pbox[i].y2 - pbox[i].y1; int w = pbox[i].x2 - pbox[i].x1 - 1; int start; if ( blit->ydir == -1 ) { srcy = blit->height - srcy - 1; } start = srcy * blit->src_pitch + srcx; DMA_BLOCK( MGA_AR0, start + w, MGA_AR3, start, MGA_FXBNDRY, ((dstx + w) << 16) | (dstx & 0xffff), MGA_YDSTLEN + MGA_EXEC, (dsty << 16) | h ); } /* Do something to flush AGP? */ /* Force reset of DWGCTL */ DMA_BLOCK( MGA_DMAPAD, 0x00000000, MGA_PLNWT, ctx->plnwt, MGA_PITCH, dev_priv->front_pitch, MGA_DWGCTL, ctx->dwgctl ); ADVANCE_DMA();}/* ================================================================ * */int mga_dma_clear( DRM_IOCTL_ARGS ){ DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_clear_t clear; LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( clear, (drm_mga_clear_t __user *)data, sizeof(clear) ); if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; WRAP_TEST_WITH_RETURN( dev_priv ); mga_dma_dispatch_clear( dev, &clear ); /* Make sure we restore the 3D state next time. */ dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; return 0;}int mga_dma_swap( DRM_IOCTL_ARGS ){ DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; LOCK_TEST_WITH_RETURN( dev, filp ); if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; WRAP_TEST_WITH_RETURN( dev_priv ); mga_dma_dispatch_swap( dev ); /* Make sure we restore the 3D state next time. */ dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; 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;}int mga_dma_indices( 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_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_iload( DRM_IOCTL_ARGS ){ DRM_DEVICE; drm_device_dma_t *dma = dev->dma; drm_mga_private_t *dev_priv = dev->dev_private; drm_buf_t *buf; drm_mga_buf_priv_t *buf_priv; drm_mga_iload_t iload; DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( iload, (drm_mga_iload_t __user *)data, sizeof(iload) );#if 0 if ( mga_do_wait_for_idle( dev_priv ) < 0 ) { if ( MGA_DMA_DEBUG ) DRM_INFO( "%s: -EBUSY\n", __FUNCTION__ ); return DRM_ERR(EBUSY); }#endif if(iload.idx < 0 || iload.idx > dma->buf_count) return DRM_ERR(EINVAL); buf = dma->buflist[iload.idx]; buf_priv = buf->dev_private; if ( mga_verify_iload( dev_priv, iload.dstorg, iload.length ) ) { mga_freelist_put( dev, buf ); return DRM_ERR(EINVAL); } WRAP_TEST_WITH_RETURN( dev_priv ); mga_dma_dispatch_iload( dev, buf, iload.dstorg, iload.length ); /* Make sure we restore the 3D state next time. */ dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; return 0;}int mga_dma_blit( DRM_IOCTL_ARGS ){ DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_blit_t blit; DRM_DEBUG( "\n" ); LOCK_TEST_WITH_RETURN( dev, filp ); DRM_COPY_FROM_USER_IOCTL( blit, (drm_mga_blit_t __user *)data, sizeof(blit) ); if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; if ( mga_verify_blit( dev_priv, blit.srcorg, blit.dstorg ) ) return DRM_ERR(EINVAL); WRAP_TEST_WITH_RETURN( dev_priv ); mga_dma_dispatch_blit( dev, &blit ); /* Make sure we restore the 3D state next time. */ dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; return 0;}int mga_getparam( DRM_IOCTL_ARGS ){ DRM_DEVICE; drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_getparam_t param; int value; if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); return DRM_ERR(EINVAL); } DRM_COPY_FROM_USER_IOCTL( param, (drm_mga_getparam_t __user *)data, sizeof(param) ); DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID ); switch( param.param ) { case MGA_PARAM_IRQ_NR: value = dev->irq; break; default: return DRM_ERR(EINVAL); } if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) { DRM_ERROR( "copy_to_user\n" ); return DRM_ERR(EFAULT); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -