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

📄 gamma_dma.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 2 页
字号:
			retcode = -EINVAL;			goto cleanup;		}		buf->pending = 1;		if (dev->last_context != buf->context		    && !(dev->queuelist[buf->context]->flags			 & _DRM_CONTEXT_PRESERVED)) {			add_wait_queue(&dev->context_wait, &entry);			current->state = TASK_INTERRUPTIBLE;				/* PRE: dev->last_context != buf->context */			DRM(context_switch)(dev, dev->last_context,					    buf->context);				/* POST: we will wait for the context				   switch and will dispatch on a later call				   when dev->last_context == buf->context.				   NOTE WE HOLD THE LOCK THROUGHOUT THIS				   TIME! */			schedule();			current->state = TASK_RUNNING;			remove_wait_queue(&dev->context_wait, &entry);			if (signal_pending(current)) {				retcode = -EINTR;				goto cleanup;			}			if (dev->last_context != buf->context) {				DRM_ERROR("Context mismatch: %d %d\n",					  dev->last_context,					  buf->context);			}		}#if DRM_DMA_HISTOGRAM		buf->time_queued     = get_cycles();		buf->time_dispatched = buf->time_queued;#endif		gamma_dma_dispatch(dev, address, length);		atomic_inc(&dev->counts[9]); /* _DRM_STAT_SPECIAL */		atomic_add(length, &dev->counts[8]); /* _DRM_STAT_PRIMARY */		if (last_buf) {			gamma_free_buffer(dev, last_buf);		}		last_buf = buf;	}cleanup:	if (last_buf) {		gamma_dma_ready(dev);		gamma_free_buffer(dev, last_buf);	}	if (must_free && !dev->context_flag) {		if (gamma_lock_free(dev, &dev->lock.hw_lock->lock,				  DRM_KERNEL_CONTEXT)) {			DRM_ERROR("\n");		}	}	clear_bit(0, &dev->interrupt_flag);	return retcode;}static int gamma_dma_send_buffers(drm_device_t *dev, drm_dma_t *d){	DECLARE_WAITQUEUE(entry, current);	drm_buf_t	  *last_buf = NULL;	int		  retcode   = 0;	drm_device_dma_t  *dma	    = dev->dma;	if (d->flags & _DRM_DMA_BLOCK) {		last_buf = dma->buflist[d->send_indices[d->send_count-1]];		add_wait_queue(&last_buf->dma_wait, &entry);	}	if ((retcode = gamma_dma_enqueue(dev, d))) {		if (d->flags & _DRM_DMA_BLOCK)			remove_wait_queue(&last_buf->dma_wait, &entry);		return retcode;	}	gamma_dma_schedule(dev, 0);	if (d->flags & _DRM_DMA_BLOCK) {		DRM_DEBUG("%d waiting\n", current->pid);		for (;;) {			current->state = TASK_INTERRUPTIBLE;			if (!last_buf->waiting && !last_buf->pending)				break; /* finished */			schedule();			if (signal_pending(current)) {				retcode = -EINTR; /* Can't restart */				break;			}		}		current->state = TASK_RUNNING;		DRM_DEBUG("%d running\n", current->pid);		remove_wait_queue(&last_buf->dma_wait, &entry);		if (!retcode		    || (last_buf->list==DRM_LIST_PEND && !last_buf->pending)) {			if (!waitqueue_active(&last_buf->dma_wait)) {				gamma_free_buffer(dev, last_buf);			}		}		if (retcode) {			DRM_ERROR("ctx%d w%d p%d c%ld i%d l%d %d/%d\n",				  d->context,				  last_buf->waiting,				  last_buf->pending,				  (long)DRM_WAITCOUNT(dev, d->context),				  last_buf->idx,				  last_buf->list,				  last_buf->pid,				  current->pid);		}	}	return retcode;}int gamma_dma(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;	int		  retcode   = 0;	drm_dma_t	  d;	if (copy_from_user(&d, (drm_dma_t *)arg, sizeof(d)))		return -EFAULT;	if (d.send_count < 0 || d.send_count > dma->buf_count) {		DRM_ERROR("Process %d trying to send %d buffers (of %d max)\n",			  current->pid, d.send_count, dma->buf_count);		return -EINVAL;	}	if (d.request_count < 0 || d.request_count > dma->buf_count) {		DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",			  current->pid, d.request_count, dma->buf_count);		return -EINVAL;	}	if (d.send_count) {		if (d.flags & _DRM_DMA_PRIORITY)			retcode = gamma_dma_priority(dev, &d);		else			retcode = gamma_dma_send_buffers(dev, &d);	}	d.granted_count = 0;	if (!retcode && d.request_count) {		retcode = gamma_dma_get_buffers(dev, &d);	}	DRM_DEBUG("%d returning, granted = %d\n",		  current->pid, d.granted_count);	if (copy_to_user((drm_dma_t *)arg, &d, sizeof(d)))		return -EFAULT;	return retcode;}/* ============================================================= * DMA initialization, cleanup */static int gamma_do_init_dma( drm_device_t *dev, drm_gamma_init_t *init ){	drm_gamma_private_t *dev_priv;	drm_device_dma_t    *dma = dev->dma;	drm_buf_t	    *buf;	int i;	struct list_head    *list;	unsigned long	    *pgt;	DRM_DEBUG( "%s\n", __FUNCTION__ );	dev_priv = DRM(alloc)( sizeof(drm_gamma_private_t),							DRM_MEM_DRIVER );	if ( !dev_priv )		return -ENOMEM;	dev->dev_private = (void *)dev_priv;	memset( dev_priv, 0, sizeof(drm_gamma_private_t) );	list_for_each(list, &dev->maplist->head) {		#warning list_entry() is needed here		drm_map_list_t *r_list = (drm_map_list_t *)list;		if( r_list->map &&		    r_list->map->type == _DRM_SHM &&		    r_list->map->flags & _DRM_CONTAINS_LOCK ) {			dev_priv->sarea = r_list->map; 			break; 		} 	}	DRM_FIND_MAP( dev_priv->mmio0, init->mmio0 );	DRM_FIND_MAP( dev_priv->mmio1, init->mmio1 );	DRM_FIND_MAP( dev_priv->mmio2, init->mmio2 );	DRM_FIND_MAP( dev_priv->mmio3, init->mmio3 );	dev_priv->sarea_priv = (drm_gamma_sarea_t *)		((u8 *)dev_priv->sarea->handle +		 init->sarea_priv_offset);	if (init->pcimode) {		buf = dma->buflist[GLINT_DRI_BUF_COUNT];		pgt = buf->address; 		for (i = 0; i < GLINT_DRI_BUF_COUNT; i++) {			buf = dma->buflist[i];			*pgt = virt_to_phys((void*)buf->address) | 0x07;			pgt++;		}		buf = dma->buflist[GLINT_DRI_BUF_COUNT];	} else {		DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset );		DRM_IOREMAP( dev_priv->buffers );		buf = dma->buflist[GLINT_DRI_BUF_COUNT];		pgt = buf->address; 		for (i = 0; i < GLINT_DRI_BUF_COUNT; i++) {			buf = dma->buflist[i];			*pgt = (unsigned long)buf->address + 0x07;			pgt++;		}		buf = dma->buflist[GLINT_DRI_BUF_COUNT];		while (GAMMA_READ(GAMMA_INFIFOSPACE) < 1);		GAMMA_WRITE( GAMMA_GDMACONTROL, 0xe) cpu_relax();	}	while (GAMMA_READ(GAMMA_INFIFOSPACE) < 2); cpu_relax();	GAMMA_WRITE( GAMMA_PAGETABLEADDR, virt_to_phys((void*)buf->address) );	GAMMA_WRITE( GAMMA_PAGETABLELENGTH, 2 );	return 0;}int gamma_do_cleanup_dma( drm_device_t *dev ){	DRM_DEBUG( "%s\n", __FUNCTION__ );	if ( dev->dev_private ) {		drm_gamma_private_t *dev_priv = dev->dev_private;		DRM_IOREMAPFREE( dev_priv->buffers );		DRM(free)( dev->dev_private, sizeof(drm_gamma_private_t),			   DRM_MEM_DRIVER );		dev->dev_private = NULL;	}	return 0;}int gamma_dma_init( 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_gamma_init_t init;	if ( copy_from_user( &init, (drm_gamma_init_t *)arg, sizeof(init) ) )		return -EFAULT;	switch ( init.func ) {	case GAMMA_INIT_DMA:		return gamma_do_init_dma( dev, &init );	case GAMMA_CLEANUP_DMA:		return gamma_do_cleanup_dma( dev );	}	return -EINVAL;}static int gamma_do_copy_dma( drm_device_t *dev, drm_gamma_copy_t *copy ){	drm_device_dma_t    *dma = dev->dma;	unsigned int        *screenbuf;	DRM_DEBUG( "%s\n", __FUNCTION__ );	/* We've DRM_RESTRICTED this DMA buffer */	screenbuf = dma->buflist[ GLINT_DRI_BUF_COUNT + 1 ]->address;#if 0	*buffer++ = 0x180;	/* Tag (FilterMode) */	*buffer++ = 0x200;	/* Allow FBColor through */	*buffer++ = 0x53B;	/* Tag */	*buffer++ = copy->Pitch;	*buffer++ = 0x53A;	/* Tag */	*buffer++ = copy->SrcAddress;	*buffer++ = 0x539;	/* Tag */	*buffer++ = copy->WidthHeight; /* Initiates transfer */	*buffer++ = 0x53C;	/* Tag - DMAOutputAddress */	*buffer++ = virt_to_phys((void*)screenbuf);	*buffer++ = 0x53D;	/* Tag - DMAOutputCount */	*buffer++ = copy->Count; /* Reads HostOutFifo BLOCKS until ..*/	/* Data now sitting in dma->buflist[ GLINT_DRI_BUF_COUNT + 1 ] */	/* Now put it back to the screen */	*buffer++ = 0x180;	/* Tag (FilterMode) */	*buffer++ = 0x400;	/* Allow Sync through */	*buffer++ = 0x538;	/* Tag - DMARectangleReadTarget */	*buffer++ = 0x155;	/* FBSourceData | count */	*buffer++ = 0x537;	/* Tag */	*buffer++ = copy->Pitch;	*buffer++ = 0x536;	/* Tag */	*buffer++ = copy->DstAddress;	*buffer++ = 0x535;	/* Tag */	*buffer++ = copy->WidthHeight; /* Initiates transfer */	*buffer++ = 0x530;	/* Tag - DMAAddr */	*buffer++ = virt_to_phys((void*)screenbuf);	*buffer++ = 0x531;	*buffer++ = copy->Count; /* initiates DMA transfer of color data */#endif	/* need to dispatch it now */	return 0;}int gamma_dma_copy( 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_gamma_copy_t copy;	if ( copy_from_user( &copy, (drm_gamma_copy_t *)arg, sizeof(copy) ) )		return -EFAULT;	return gamma_do_copy_dma( dev, &copy );}/* ============================================================= * Per Context SAREA Support */int gamma_getsareactx(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_ctx_priv_map_t request;	drm_map_t *map;	if (copy_from_user(&request,			   (drm_ctx_priv_map_t *)arg,			   sizeof(request)))		return -EFAULT;	down(&dev->struct_sem);	if ((int)request.ctx_id >= dev->max_context) {		up(&dev->struct_sem);		return -EINVAL;	}	map = dev->context_sareas[request.ctx_id];	up(&dev->struct_sem);	request.handle = map->handle;	if (copy_to_user((drm_ctx_priv_map_t *)arg, &request, sizeof(request)))		return -EFAULT;	return 0;}int gamma_setsareactx(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_ctx_priv_map_t request;	drm_map_t *map = NULL;	drm_map_list_t *r_list;	struct list_head *list;	if (copy_from_user(&request,			   (drm_ctx_priv_map_t *)arg,			   sizeof(request)))		return -EFAULT;	down(&dev->struct_sem);	r_list = NULL;	list_for_each(list, &dev->maplist->head) {		r_list = (drm_map_list_t *)list;		if(r_list->map &&		   r_list->map->handle == request.handle) break;	}	if (list == &(dev->maplist->head)) {		up(&dev->struct_sem);		return -EINVAL;	}	map = r_list->map;	up(&dev->struct_sem);	if (!map) return -EINVAL;	down(&dev->struct_sem);	if ((int)request.ctx_id >= dev->max_context) {		up(&dev->struct_sem);		return -EINVAL;	}	dev->context_sareas[request.ctx_id] = map;	up(&dev->struct_sem);	return 0;}

⌨️ 快捷键说明

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