⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i830_dma.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	BEGIN_LP_RING(2);	OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);	OUT_RING(0);	ADVANCE_LP_RING();	BEGIN_LP_RING(6);	OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP);	OUT_RING(0);	if (dev_priv->current_page == 0) {		OUT_RING(dev_priv->back_offset);		dev_priv->current_page = 1;	} else {		OUT_RING(dev_priv->front_offset);		dev_priv->current_page = 0;	}	OUT_RING(0);	ADVANCE_LP_RING();	BEGIN_LP_RING(2);	OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP);	OUT_RING(0);	ADVANCE_LP_RING();	dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;}static void i830_dma_dispatch_vertex(drm_device_t * dev,				     drm_buf_t * buf, int discard, int used){	drm_i830_private_t *dev_priv = dev->dev_private;	drm_i830_buf_priv_t *buf_priv = buf->dev_private;	drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;	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;	RING_LOCALS;	i830_kernel_lost_context(dev);	if (nbox > I830_NR_SAREA_CLIPRECTS)		nbox = I830_NR_SAREA_CLIPRECTS;	if (discard) {		u = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT,			    I830_BUF_HARDWARE);		if (u != I830_BUF_CLIENT) {			DRM_DEBUG("xxxx 2\n");		}	}	if (used > 4 * 1023)		used = 0;	if (sarea_priv->dirty)		i830EmitState(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("i830_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 == I830_BUF_MAPPED) {		u32 *vp = buf_priv->kernel_virtual;		vp[0] = (GFX_OP_PRIMITIVE |			 sarea_priv->vertex_prim | ((used / 4) - 2));		if (dev_priv->use_mi_batchbuffer_start) {			vp[used / 4] = MI_BATCH_BUFFER_END;			used += 4;		}		if (used & 4) {			vp[used / 4] = 0;			used += 4;		}		i830_unmap_buffer(buf);	}	if (used) {		do {			if (i < nbox) {				BEGIN_LP_RING(6);				OUT_RING(GFX_OP_DRAWRECT_INFO);				OUT_RING(sarea_priv->					 BufferState[I830_DESTREG_DR1]);				OUT_RING(box[i].x1 | (box[i].y1 << 16));				OUT_RING(box[i].x2 | (box[i].y2 << 16));				OUT_RING(sarea_priv->					 BufferState[I830_DESTREG_DR4]);				OUT_RING(0);				ADVANCE_LP_RING();			}			if (dev_priv->use_mi_batchbuffer_start) {				BEGIN_LP_RING(2);				OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));				OUT_RING(start | MI_BATCH_NON_SECURE);				ADVANCE_LP_RING();			} else {				BEGIN_LP_RING(4);				OUT_RING(MI_BATCH_BUFFER);				OUT_RING(start | MI_BATCH_NON_SECURE);				OUT_RING(start + used - 4);				OUT_RING(0);				ADVANCE_LP_RING();			}		} while (++i < nbox);	}	if (discard) {		dev_priv->counter++;		(void)cmpxchg(buf_priv->in_use, I830_BUF_CLIENT,			      I830_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(I830_BUF_FREE);		OUT_RING(CMD_REPORT_HEAD);		OUT_RING(0);		ADVANCE_LP_RING();	}}static void i830_dma_quiescent(drm_device_t * dev){	drm_i830_private_t *dev_priv = dev->dev_private;	RING_LOCALS;	i830_kernel_lost_context(dev);	BEGIN_LP_RING(4);	OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);	OUT_RING(CMD_REPORT_HEAD);	OUT_RING(0);	OUT_RING(0);	ADVANCE_LP_RING();	i830_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);}static int i830_flush_queue(drm_device_t * dev){	drm_i830_private_t *dev_priv = dev->dev_private;	drm_device_dma_t *dma = dev->dma;	int i, ret = 0;	RING_LOCALS;	i830_kernel_lost_context(dev);	BEGIN_LP_RING(2);	OUT_RING(CMD_REPORT_HEAD);	OUT_RING(0);	ADVANCE_LP_RING();	i830_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);	for (i = 0; i < dma->buf_count; i++) {		drm_buf_t *buf = dma->buflist[i];		drm_i830_buf_priv_t *buf_priv = buf->dev_private;		int used = cmpxchg(buf_priv->in_use, I830_BUF_HARDWARE,				   I830_BUF_FREE);		if (used == I830_BUF_HARDWARE)			DRM_DEBUG("reclaimed from HARDWARE\n");		if (used == I830_BUF_CLIENT)			DRM_DEBUG("still on client\n");	}	return ret;}/* Must be called with the lock held */void i830_reclaim_buffers(drm_device_t * dev, struct file *filp){	drm_device_dma_t *dma = dev->dma;	int i;	if (!dma)		return;	if (!dev->dev_private)		return;	if (!dma->buflist)		return;	i830_flush_queue(dev);	for (i = 0; i < dma->buf_count; i++) {		drm_buf_t *buf = dma->buflist[i];		drm_i830_buf_priv_t *buf_priv = buf->dev_private;		if (buf->filp == filp && buf_priv) {			int used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT,					   I830_BUF_FREE);			if (used == I830_BUF_CLIENT)				DRM_DEBUG("reclaimed from client\n");			if (buf_priv->currently_mapped == I830_BUF_MAPPED)				buf_priv->currently_mapped = I830_BUF_UNMAPPED;		}	}}static int i830_flush_ioctl(struct inode *inode, struct file *filp,			    unsigned int cmd, unsigned long arg){	drm_file_t *priv = filp->private_data;	drm_device_t *dev = priv->head->dev;	LOCK_TEST_WITH_RETURN(dev, filp);	i830_flush_queue(dev);	return 0;}static int i830_dma_vertex(struct inode *inode, struct file *filp,			   unsigned int cmd, unsigned long arg){	drm_file_t *priv = filp->private_data;	drm_device_t *dev = priv->head->dev;	drm_device_dma_t *dma = dev->dma;	drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;	u32 *hw_status = dev_priv->hw_status_page;	drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *)	    dev_priv->sarea_priv;	drm_i830_vertex_t vertex;	if (copy_from_user	    (&vertex, (drm_i830_vertex_t __user *) arg, sizeof(vertex)))		return -EFAULT;	LOCK_TEST_WITH_RETURN(dev, filp);	DRM_DEBUG("i830 dma vertex, idx %d used %d discard %d\n",		  vertex.idx, vertex.used, vertex.discard);	if (vertex.idx < 0 || vertex.idx > dma->buf_count)		return -EINVAL;	i830_dma_dispatch_vertex(dev,				 dma->buflist[vertex.idx],				 vertex.discard, vertex.used);	sarea_priv->last_enqueue = dev_priv->counter - 1;	sarea_priv->last_dispatch = (int)hw_status[5];	return 0;}static int i830_clear_bufs(struct inode *inode, struct file *filp,			   unsigned int cmd, unsigned long arg){	drm_file_t *priv = filp->private_data;	drm_device_t *dev = priv->head->dev;	drm_i830_clear_t clear;	if (copy_from_user	    (&clear, (drm_i830_clear_t __user *) arg, sizeof(clear)))		return -EFAULT;	LOCK_TEST_WITH_RETURN(dev, filp);	/* GH: Someone's doing nasty things... */	if (!dev->dev_private) {		return -EINVAL;	}	i830_dma_dispatch_clear(dev, clear.flags,				clear.clear_color,				clear.clear_depth, clear.clear_depthmask);	return 0;}static int i830_swap_bufs(struct inode *inode, struct file *filp,			  unsigned int cmd, unsigned long arg){	drm_file_t *priv = filp->private_data;	drm_device_t *dev = priv->head->dev;	DRM_DEBUG("i830_swap_bufs\n");	LOCK_TEST_WITH_RETURN(dev, filp);	i830_dma_dispatch_swap(dev);	return 0;}/* Not sure why this isn't set all the time: */static void i830_do_init_pageflip(drm_device_t * dev){	drm_i830_private_t *dev_priv = dev->dev_private;	DRM_DEBUG("%s\n", __FUNCTION__);	dev_priv->page_flipping = 1;	dev_priv->current_page = 0;	dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;}static int i830_do_cleanup_pageflip(drm_device_t * dev){	drm_i830_private_t *dev_priv = dev->dev_private;	DRM_DEBUG("%s\n", __FUNCTION__);	if (dev_priv->current_page != 0)		i830_dma_dispatch_flip(dev);	dev_priv->page_flipping = 0;	return 0;}static int i830_flip_bufs(struct inode *inode, struct file *filp,			  unsigned int cmd, unsigned long arg){	drm_file_t *priv = filp->private_data;	drm_device_t *dev = priv->head->dev;	drm_i830_private_t *dev_priv = dev->dev_private;	DRM_DEBUG("%s\n", __FUNCTION__);	LOCK_TEST_WITH_RETURN(dev, filp);	if (!dev_priv->page_flipping)		i830_do_init_pageflip(dev);	i830_dma_dispatch_flip(dev);	return 0;}static int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd,		       unsigned long arg){	drm_file_t *priv = filp->private_data;	drm_device_t *dev = priv->head->dev;	drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;	u32 *hw_status = dev_priv->hw_status_page;	drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *)	    dev_priv->sarea_priv;	sarea_priv->last_dispatch = (int)hw_status[5];	return 0;}static int i830_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,		       unsigned long arg){	drm_file_t *priv = filp->private_data;	drm_device_t *dev = priv->head->dev;	int retcode = 0;	drm_i830_dma_t d;	drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;	u32 *hw_status = dev_priv->hw_status_page;	drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *)	    dev_priv->sarea_priv;	DRM_DEBUG("getbuf\n");	if (copy_from_user(&d, (drm_i830_dma_t __user *) arg, sizeof(d)))		return -EFAULT;	LOCK_TEST_WITH_RETURN(dev, filp);	d.granted = 0;	retcode = i830_dma_get_buffer(dev, &d, filp);	DRM_DEBUG("i830_dma: %d returning %d, granted = %d\n",		  current->pid, retcode, d.granted);	if (copy_to_user((drm_dma_t __user *) arg, &d, sizeof(d)))		return -EFAULT;	sarea_priv->last_dispatch = (int)hw_status[5];	return retcode;}static int i830_copybuf(struct inode *inode,			struct file *filp, unsigned int cmd, unsigned long arg){	/* Never copy - 2.4.x doesn't need it */	return 0;}static int i830_docopy(struct inode *inode, struct file *filp, unsigned int cmd,		       unsigned long arg){	return 0;}static int i830_getparam(struct inode *inode, struct file *filp,			 unsigned int cmd, unsigned long arg){	drm_file_t *priv = filp->private_data;	drm_device_t *dev = priv->head->dev;	drm_i830_private_t *dev_priv = dev->dev_private;	drm_i830_getparam_t param;	int value;	if (!dev_priv) {		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);		return -EINVAL;	}	if (copy_from_user	    (&param, (drm_i830_getparam_t __user *) arg, sizeof(param)))		return -EFAULT;	switch (param.param) {	case I830_PARAM_IRQ_ACTIVE:		value = dev->irq_enabled;		break;	default:		return -EINVAL;	}	if (copy_to_user(param.value, &value, sizeof(int))) {		DRM_ERROR("copy_to_user\n");		return -EFAULT;	}	return 0;}static int i830_setparam(struct inode *inode, struct file *filp,			 unsigned int cmd, unsigned long arg){	drm_file_t *priv = filp->private_data;	drm_device_t *dev = priv->head->dev;	drm_i830_private_t *dev_priv = dev->dev_private;	drm_i830_setparam_t param;	if (!dev_priv) {		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);		return -EINVAL;	}	if (copy_from_user	    (&param, (drm_i830_setparam_t __user *) arg, sizeof(param)))		return -EFAULT;	switch (param.param) {	case I830_SETPARAM_USE_MI_BATCHBUFFER_START:		dev_priv->use_mi_batchbuffer_start = param.value;		break;	default:		return -EINVAL;	}	return 0;}void i830_driver_pretakedown(drm_device_t * dev){	i830_dma_cleanup(dev);}void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp){	if (dev->dev_private) {		drm_i830_private_t *dev_priv = dev->dev_private;		if (dev_priv->page_flipping) {			i830_do_cleanup_pageflip(dev);		}	}}void i830_driver_release(drm_device_t * dev, struct file *filp){	i830_reclaim_buffers(dev, filp);}int i830_driver_dma_quiescent(drm_device_t * dev){	i830_dma_quiescent(dev);	return 0;}drm_ioctl_desc_t i830_ioctls[] = {	[DRM_IOCTL_NR(DRM_I830_INIT)] = {i830_dma_init, 1, 1},	[DRM_IOCTL_NR(DRM_I830_VERTEX)] = {i830_dma_vertex, 1, 0},	[DRM_IOCTL_NR(DRM_I830_CLEAR)] = {i830_clear_bufs, 1, 0},	[DRM_IOCTL_NR(DRM_I830_FLUSH)] = {i830_flush_ioctl, 1, 0},	[DRM_IOCTL_NR(DRM_I830_GETAGE)] = {i830_getage, 1, 0},	[DRM_IOCTL_NR(DRM_I830_GETBUF)] = {i830_getbuf, 1, 0},	[DRM_IOCTL_NR(DRM_I830_SWAP)] = {i830_swap_bufs, 1, 0},	[DRM_IOCTL_NR(DRM_I830_COPY)] = {i830_copybuf, 1, 0},	[DRM_IOCTL_NR(DRM_I830_DOCOPY)] = {i830_docopy, 1, 0},	[DRM_IOCTL_NR(DRM_I830_FLIP)] = {i830_flip_bufs, 1, 0},	[DRM_IOCTL_NR(DRM_I830_IRQ_EMIT)] = {i830_irq_emit, 1, 0},	[DRM_IOCTL_NR(DRM_I830_IRQ_WAIT)] = {i830_irq_wait, 1, 0},	[DRM_IOCTL_NR(DRM_I830_GETPARAM)] = {i830_getparam, 1, 0},	[DRM_IOCTL_NR(DRM_I830_SETPARAM)] = {i830_setparam, 1, 0}};int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls);/** * Determine if the device really is AGP or not. * * All Intel graphics chipsets are treated as AGP, even if they are really * PCI-e. * * \param dev   The device to be tested. * * \returns * A value of 1 is always retured to indictate every i8xx is AGP. */int i830_driver_device_is_agp(drm_device_t * dev){	return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -