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

📄 r128_cce.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	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_token = init->buffers_offset;	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 = (unsigned long)dev->sg->virtual;	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		dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN;		dev_priv->gart_info.addr = dev_priv->gart_info.bus_addr = 0;		dev_priv->gart_info.is_pcie = 0;		if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {			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->gart_info.bus_addr);#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 (dev_priv->gart_info.bus_addr)				if (!drm_ati_pcigart_cleanup(dev,							     &dev_priv->							     gart_info))					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;}#endifstatic drm_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 + -