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

📄 r128_cce.c

📁 h内核
💻 C
📖 第 1 页 / 共 2 页
字号:
		r128_do_cleanup_cce( dev );		return DRM_ERR(EINVAL);	}	dev_priv->cce_ring = drm_core_findmap(dev, init->ring_offset);	if(!dev_priv->cce_ring) {		DRM_ERROR("could not find cce ring region!\n");		dev->dev_private = (void *)dev_priv;		r128_do_cleanup_cce( dev );		return DRM_ERR(EINVAL);	}	dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset);	if(!dev_priv->ring_rptr) {		DRM_ERROR("could not find ring read pointer!\n");		dev->dev_private = (void *)dev_priv;		r128_do_cleanup_cce( dev );		return DRM_ERR(EINVAL);	}	dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);	if(!dev->agp_buffer_map) {		DRM_ERROR("could not find dma buffer region!\n");		dev->dev_private = (void *)dev_priv;		r128_do_cleanup_cce( dev );		return DRM_ERR(EINVAL);	}	if ( !dev_priv->is_pci ) {		dev_priv->agp_textures = drm_core_findmap(dev, init->agp_textures_offset);		if(!dev_priv->agp_textures) {			DRM_ERROR("could not find agp texture region!\n");			dev->dev_private = (void *)dev_priv;			r128_do_cleanup_cce( dev );			return DRM_ERR(EINVAL);		}	}	dev_priv->sarea_priv =		(drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle +				     init->sarea_priv_offset);#if __OS_HAS_AGP	if ( !dev_priv->is_pci ) {		drm_core_ioremap( dev_priv->cce_ring, dev );		drm_core_ioremap( dev_priv->ring_rptr, dev );		drm_core_ioremap( dev->agp_buffer_map, dev );		if(!dev_priv->cce_ring->handle ||		   !dev_priv->ring_rptr->handle ||		   !dev->agp_buffer_map->handle) {			DRM_ERROR("Could not ioremap agp regions!\n");			dev->dev_private = (void *)dev_priv;			r128_do_cleanup_cce( dev );			return DRM_ERR(ENOMEM);		}	} else#endif	{		dev_priv->cce_ring->handle =			(void *)dev_priv->cce_ring->offset;		dev_priv->ring_rptr->handle =			(void *)dev_priv->ring_rptr->offset;		dev->agp_buffer_map->handle = (void *)dev->agp_buffer_map->offset;	}#if __OS_HAS_AGP	if ( !dev_priv->is_pci )		dev_priv->cce_buffers_offset = dev->agp->base;	else#endif		dev_priv->cce_buffers_offset = dev->sg->handle;	dev_priv->ring.start = (u32 *)dev_priv->cce_ring->handle;	dev_priv->ring.end = ((u32 *)dev_priv->cce_ring->handle			      + init->ring_size / sizeof(u32));	dev_priv->ring.size = init->ring_size;	dev_priv->ring.size_l2qw = drm_order( init->ring_size / 8 );	dev_priv->ring.tail_mask =		(dev_priv->ring.size / sizeof(u32)) - 1;	dev_priv->ring.high_mark = 128;	dev_priv->sarea_priv->last_frame = 0;	R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame );	dev_priv->sarea_priv->last_dispatch = 0;	R128_WRITE( R128_LAST_DISPATCH_REG,		    dev_priv->sarea_priv->last_dispatch );#if __OS_HAS_AGP	if ( dev_priv->is_pci ) {#endif		if (!drm_ati_pcigart_init( dev, &dev_priv->phys_pci_gart,     					    &dev_priv->bus_pci_gart) ) {			DRM_ERROR( "failed to init PCI GART!\n" );			dev->dev_private = (void *)dev_priv;			r128_do_cleanup_cce( dev );			return DRM_ERR(ENOMEM);		}		R128_WRITE( R128_PCI_GART_PAGE, dev_priv->bus_pci_gart );#if __OS_HAS_AGP	}#endif	r128_cce_init_ring_buffer( dev, dev_priv );	r128_cce_load_microcode( dev_priv );	dev->dev_private = (void *)dev_priv;	r128_do_engine_reset( dev );	return 0;}int r128_do_cleanup_cce( drm_device_t *dev ){	/* Make sure interrupts are disabled here because the uninstall ioctl	 * may not have been called from userspace and after dev_private	 * is freed, it's too late.	 */	if ( dev->irq_enabled ) drm_irq_uninstall(dev);	if ( dev->dev_private ) {		drm_r128_private_t *dev_priv = dev->dev_private;#if __OS_HAS_AGP		if ( !dev_priv->is_pci ) {			if ( dev_priv->cce_ring != NULL )				drm_core_ioremapfree( dev_priv->cce_ring, dev );			if ( dev_priv->ring_rptr != NULL )				drm_core_ioremapfree( dev_priv->ring_rptr, dev );			if ( dev->agp_buffer_map != NULL )				drm_core_ioremapfree( dev->agp_buffer_map, dev );		} else#endif		{			if (!drm_ati_pcigart_cleanup( dev,						dev_priv->phys_pci_gart,						dev_priv->bus_pci_gart ))				DRM_ERROR( "failed to cleanup PCI GART!\n" );		}		drm_free( dev->dev_private, sizeof(drm_r128_private_t),			   DRM_MEM_DRIVER );		dev->dev_private = NULL;	}	return 0;}int r128_cce_init( DRM_IOCTL_ARGS ){	DRM_DEVICE;	drm_r128_init_t init;	DRM_DEBUG( "\n" );	LOCK_TEST_WITH_RETURN( dev, filp );	DRM_COPY_FROM_USER_IOCTL( init, (drm_r128_init_t __user *)data, sizeof(init) );	switch ( init.func ) {	case R128_INIT_CCE:		return r128_do_init_cce( dev, &init );	case R128_CLEANUP_CCE:		return r128_do_cleanup_cce( dev );	}	return DRM_ERR(EINVAL);}int r128_cce_start( DRM_IOCTL_ARGS ){	DRM_DEVICE;	drm_r128_private_t *dev_priv = dev->dev_private;	DRM_DEBUG( "\n" );	LOCK_TEST_WITH_RETURN( dev, filp );	if ( dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4 ) {		DRM_DEBUG( "%s while CCE running\n", __FUNCTION__ );		return 0;	}	r128_do_cce_start( dev_priv );	return 0;}/* Stop the CCE.  The engine must have been idled before calling this * routine. */int r128_cce_stop( DRM_IOCTL_ARGS ){	DRM_DEVICE;	drm_r128_private_t *dev_priv = dev->dev_private;	drm_r128_cce_stop_t stop;	int ret;	DRM_DEBUG( "\n" );	LOCK_TEST_WITH_RETURN( dev, filp );	DRM_COPY_FROM_USER_IOCTL(stop, (drm_r128_cce_stop_t __user *)data, sizeof(stop) );	/* Flush any pending CCE commands.  This ensures any outstanding	 * commands are exectuted by the engine before we turn it off.	 */	if ( stop.flush ) {		r128_do_cce_flush( dev_priv );	}	/* If we fail to make the engine go idle, we return an error	 * code so that the DRM ioctl wrapper can try again.	 */	if ( stop.idle ) {		ret = r128_do_cce_idle( dev_priv );		if ( ret ) return ret;	}	/* Finally, we can turn off the CCE.  If the engine isn't idle,	 * we will get some dropped triangles as they won't be fully	 * rendered before the CCE is shut down.	 */	r128_do_cce_stop( dev_priv );	/* Reset the engine */	r128_do_engine_reset( dev );	return 0;}/* Just reset the CCE ring.  Called as part of an X Server engine reset. */int r128_cce_reset( DRM_IOCTL_ARGS ){	DRM_DEVICE;	drm_r128_private_t *dev_priv = dev->dev_private;	DRM_DEBUG( "\n" );	LOCK_TEST_WITH_RETURN( dev, filp );	if ( !dev_priv ) {		DRM_DEBUG( "%s called before init done\n", __FUNCTION__ );		return DRM_ERR(EINVAL);	}	r128_do_cce_reset( dev_priv );	/* The CCE is no longer running after an engine reset */	dev_priv->cce_running = 0;	return 0;}int r128_cce_idle( DRM_IOCTL_ARGS ){	DRM_DEVICE;	drm_r128_private_t *dev_priv = dev->dev_private;	DRM_DEBUG( "\n" );	LOCK_TEST_WITH_RETURN( dev, filp );	if ( dev_priv->cce_running ) {		r128_do_cce_flush( dev_priv );	}	return r128_do_cce_idle( dev_priv );}int r128_engine_reset( DRM_IOCTL_ARGS ){	DRM_DEVICE;	DRM_DEBUG( "\n" );	LOCK_TEST_WITH_RETURN( dev, filp );	return r128_do_engine_reset( dev );}int r128_fullscreen( DRM_IOCTL_ARGS ){	return DRM_ERR(EINVAL);}/* ================================================================ * Freelist management */#define R128_BUFFER_USED	0xffffffff#define R128_BUFFER_FREE	0#if 0static int r128_freelist_init( drm_device_t *dev ){	drm_device_dma_t *dma = dev->dma;	drm_r128_private_t *dev_priv = dev->dev_private;	drm_buf_t *buf;	drm_r128_buf_priv_t *buf_priv;	drm_r128_freelist_t *entry;	int i;	dev_priv->head = drm_alloc( sizeof(drm_r128_freelist_t),				     DRM_MEM_DRIVER );	if ( dev_priv->head == NULL )		return DRM_ERR(ENOMEM);	memset( dev_priv->head, 0, sizeof(drm_r128_freelist_t) );	dev_priv->head->age = R128_BUFFER_USED;	for ( i = 0 ; i < dma->buf_count ; i++ ) {		buf = dma->buflist[i];		buf_priv = buf->dev_private;		entry = drm_alloc( sizeof(drm_r128_freelist_t),				    DRM_MEM_DRIVER );		if ( !entry ) return DRM_ERR(ENOMEM);		entry->age = R128_BUFFER_FREE;		entry->buf = buf;		entry->prev = dev_priv->head;		entry->next = dev_priv->head->next;		if ( !entry->next )			dev_priv->tail = entry;		buf_priv->discard = 0;		buf_priv->dispatched = 0;		buf_priv->list_entry = entry;		dev_priv->head->next = entry;		if ( dev_priv->head->next )			dev_priv->head->next->prev = entry;	}	return 0;}#endifdrm_buf_t *r128_freelist_get( drm_device_t *dev ){	drm_device_dma_t *dma = dev->dma;	drm_r128_private_t *dev_priv = dev->dev_private;	drm_r128_buf_priv_t *buf_priv;	drm_buf_t *buf;	int i, t;	/* FIXME: Optimize -- use freelist code */	for ( i = 0 ; i < dma->buf_count ; i++ ) {		buf = dma->buflist[i];		buf_priv = buf->dev_private;		if ( buf->filp == 0 )			return buf;	}	for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) {		u32 done_age = R128_READ( R128_LAST_DISPATCH_REG );		for ( i = 0 ; i < dma->buf_count ; i++ ) {			buf = dma->buflist[i];			buf_priv = buf->dev_private;			if ( buf->pending && buf_priv->age <= done_age ) {				/* The buffer has been processed, so it				 * can now be used.				 */				buf->pending = 0;				return buf;			}		}		DRM_UDELAY( 1 );	}	DRM_DEBUG( "returning NULL!\n" );	return NULL;}void r128_freelist_reset( drm_device_t *dev ){	drm_device_dma_t *dma = dev->dma;	int i;	for ( i = 0 ; i < dma->buf_count ; i++ ) {		drm_buf_t *buf = dma->buflist[i];		drm_r128_buf_priv_t *buf_priv = buf->dev_private;		buf_priv->age = 0;	}}/* ================================================================ * CCE command submission */int r128_wait_ring( drm_r128_private_t *dev_priv, int n ){	drm_r128_ring_buffer_t *ring = &dev_priv->ring;	int i;	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {		r128_update_ring_snapshot( dev_priv );		if ( ring->space >= n )			return 0;		DRM_UDELAY( 1 );	}	/* FIXME: This is being ignored... */	DRM_ERROR( "failed!\n" );	return DRM_ERR(EBUSY);}static int r128_cce_get_buffers( DRMFILE filp, drm_device_t *dev, drm_dma_t *d ){	int i;	drm_buf_t *buf;	for ( i = d->granted_count ; i < d->request_count ; i++ ) {		buf = r128_freelist_get( dev );		if ( !buf ) return DRM_ERR(EAGAIN);		buf->filp = filp;		if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx,				   sizeof(buf->idx) ) )			return DRM_ERR(EFAULT);		if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total,				   sizeof(buf->total) ) )			return DRM_ERR(EFAULT);		d->granted_count++;	}	return 0;}int r128_cce_buffers( DRM_IOCTL_ARGS ){	DRM_DEVICE;	drm_device_dma_t *dma = dev->dma;	int ret = 0;	drm_dma_t __user *argp = (void __user *)data;	drm_dma_t d;	LOCK_TEST_WITH_RETURN( dev, filp );	DRM_COPY_FROM_USER_IOCTL( d, argp, sizeof(d) );	/* Please don't send us buffers.	 */	if ( d.send_count != 0 ) {		DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n",			   DRM_CURRENTPID, d.send_count );		return DRM_ERR(EINVAL);	}	/* We'll send you buffers.	 */	if ( d.request_count < 0 || d.request_count > dma->buf_count ) {		DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n",			   DRM_CURRENTPID, d.request_count, dma->buf_count );		return DRM_ERR(EINVAL);	}	d.granted_count = 0;	if ( d.request_count ) {		ret = r128_cce_get_buffers( filp, dev, &d );	}	DRM_COPY_TO_USER_IOCTL(argp, d, sizeof(d) );	return ret;}

⌨️ 快捷键说明

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