diff options
| -rw-r--r-- | linux-core/Makefile.kernel | 2 | ||||
| -rw-r--r-- | linux-core/ati_pcigart.c | 145 | ||||
| -rw-r--r-- | linux-core/drmP.h | 11 | ||||
| -rw-r--r-- | linux-core/radeon_buffer.c | 129 | ||||
| -rw-r--r-- | linux-core/radeon_drv.c | 39 | ||||
| -rw-r--r-- | linux-core/radeon_fence.c | 125 | ||||
| -rw-r--r-- | shared-core/radeon_cp.c | 3 | ||||
| -rw-r--r-- | shared-core/radeon_drm.h | 9 | ||||
| -rw-r--r-- | shared-core/radeon_drv.h | 50 | ||||
| -rw-r--r-- | shared-core/radeon_irq.c | 22 | 
10 files changed, 522 insertions, 13 deletions
| diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index 6f5b021b..510509cc 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -27,7 +27,7 @@ nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \  		nv04_fb.o nv10_fb.o nv40_fb.o \  		nv04_graph.o nv10_graph.o nv20_graph.o nv30_graph.o \  		nv40_graph.o -radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o +radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o radeon_fence.o radeon_buffer.o  sis-objs    := sis_drv.o sis_mm.o  ffb-objs    := ffb_drv.o ffb_context.o  savage-objs := savage_drv.o savage_bci.o savage_state.o diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c index 524618a8..66742bbc 100644 --- a/linux-core/ati_pcigart.c +++ b/linux-core/ati_pcigart.c @@ -238,3 +238,148 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)  	return ret;  }  EXPORT_SYMBOL(drm_ati_pcigart_init); + +static int ati_pcigart_needs_unbind_cache_adjust(drm_ttm_backend_t *backend) +{ +	return ((backend->flags & DRM_BE_FLAG_BOUND_CACHED) ? 0 : 1); +} + +void ati_pcigart_alloc_page_array(size_t size, struct ati_pcigart_memory *mem) +{ +        mem->memory = NULL; +        mem->flags = 0; + +        if (size <= 2*PAGE_SIZE) +                mem->memory = kmalloc(size, GFP_KERNEL | __GFP_NORETRY); +        if (mem->memory == NULL) { +                mem->memory = vmalloc(size); +                mem->flags |= ATI_PCIGART_FLAG_VMALLOC; +        } +} + +static int ati_pcigart_populate(drm_ttm_backend_t *backend, +				unsigned long num_pages, +				struct page **pages) +{ +	ati_pcigart_ttm_priv *atipci_priv = (ati_pcigart_ttm_priv *)backend->private;	 +	struct page **cur_page, **last_page = pages + num_pages; +	struct ati_pcigart_memory *mem; +        unsigned long alloc_size = num_pages * sizeof(struct page *); + +	DRM_DEBUG("%d\n", num_pages); +	if (drm_alloc_memctl(num_pages * sizeof(void *))) +		return -1; + +	mem = drm_alloc(sizeof(struct ati_pcigart_memory), DRM_MEM_MAPPINGS); +	if (!mem) { +		drm_free_memctl(num_pages * sizeof(void *)); +		return -1; +	} + +        ati_pcigart_alloc_page_array(alloc_size, mem); +        mem->page_count = 0; +        for (cur_page = pages; cur_page < last_page; ++cur_page) { +                mem->memory[mem->page_count++] = page_to_phys(*cur_page); +        } +	atipci_priv->mem = mem; +	return 0; +} + +static int ati_pcigart_bind_ttm(drm_ttm_backend_t *backend, +				unsigned long offset, +				int cached) +{ +	ati_pcigart_ttm_priv *atipci_priv = (ati_pcigart_ttm_priv *)backend->private; +        struct ati_pcigart_memory *mem = atipci_priv->mem; +        off_t j; + +        j = offset; +        while (j < (pg_start + mem->page_count)) { +                j++; +        } + +        for (i = 0, j = offset; i < mem->page_count; i++, j++) { +                /* write value */ +        } + +        /* need to traverse table and add entries */ +	DRM_DEBUG("\n"); +	return -1; +} + +static int ati_pcigart_unbind_ttm(drm_ttm_backend_t *backend) +{ +	ati_pcigart_ttm_priv *atipci_priv = (ati_pcigart_ttm_priv *)backend->private; +	 +	DRM_DEBUG("\n"); +	return -1; +} + +static void ati_pcigart_clear_ttm(drm_ttm_backend_t *backend) +{ +	ati_pcigart_ttm_priv *atipci_priv = (ati_pcigart_ttm_priv *)backend->private; +	struct ati_pcigart_memory *mem = atipci_priv->mem; + +	DRM_DEBUG("\n");	 +	if (mem) { +		unsigned long num_pages = mem->page_count; +		backend->unbind(backend); +		/* free test */ +		drm_free(mem, sizeof(struct ati_pcigart_memory), DRM_MEM_MAPPINGS); +		drm_free_memctl(num_pages * sizeof(void *)); +	} +	atipci_priv->mem = NULL; +} + +static void ati_pcigart_destroy_ttm(drm_ttm_backend_t *backend) +{ +	ati_pcigart_ttm_priv *atipci_priv; + +	if (backend) { +		DRM_DEBUG("\n"); +		atipci_priv = (ati_pcigart_ttm_priv *)backend->private; +		if (atipci_priv) { +			if (atipci_priv->mem) { +				backend->clear(backend); +			} +			drm_ctl_free(atipci_priv, sizeof(*atipci_priv), DRM_MEM_MAPPINGS); +			backend->private = NULL; +		} +		if (backend->flags & DRM_BE_FLAG_NEEDS_FREE) { +			drm_ctl_free(backend, sizeof(*backend), DRM_MEM_MAPPINGS); +		} +	} +} + + +drm_ttm_backend_t *ati_pcigart_init_ttm(struct drm_device *dev, +					drm_ttm_backend_t *backend) +{ +	drm_ttm_backend_t *atipci_be; +	ati_pcigart_ttm_priv *atipci_priv; + +	atipci_be = (backend != NULL) ? backend :  +		drm_ctl_calloc(1, sizeof (*atipci_be), DRM_MEM_MAPPINGS); + +	if (!atipci_be) +		return NULL; + +	atipci_priv = drm_ctl_calloc(1, sizeof(*atipci_priv), DRM_MEM_MAPPINGS); +	if (!atipci_priv) { +		drm_ctl_free(atipci_be, sizeof(*atipci_be), DRM_MEM_MAPPINGS); +		return NULL; +	} + +	atipci_priv->populated = FALSE; +	atipci_be->needs_ub_cache_adjust = ati_pcigart_needs_unbind_cache_adjust; +	atipci_be->populate = ati_pcigart_populate; +	atipci_be->clear = ati_pcigart_clear_ttm; +	atipci_be->bind = ati_pcigart_bind_ttm; +	atipci_be->unbind = ati_pcigart_unbind_ttm; +	atipci_be->destroy = ati_pcigart_destroy_ttm; +	 +	DRM_FLAG_MASKED(atipci_be->flags, (backend == NULL) ? DRM_BE_FLAG_NEEDS_FREE : 0, DRM_BE_FLAG_NEEDS_FREE); +	atipci_be->drm_map_type = _DRM_SCATTER_GATHER; +	return atipci_be; +} +EXPORT_SYMBOL(ati_pcigart_init_ttm); diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 94cb4eee..ec432b2a 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -843,6 +843,17 @@ typedef struct drm_agp_ttm_backend {  } drm_agp_ttm_backend_t;  #endif +#define ATI_PCIGART_FLAG_VMALLOC 1 +struct ati_pcigart_memory { +	size_t page_count; +	unsigned long *memory; +	int flags; +}; + +typedef struct ati_pcigart_ttm_priv { +	int populated; +	struct ati_pcigart_memory *mem; +} ati_pcigart_ttm_priv;  static __inline__ int drm_core_check_feature(struct drm_device *dev,  					     int feature) diff --git a/linux-core/radeon_buffer.c b/linux-core/radeon_buffer.c new file mode 100644 index 00000000..dd387604 --- /dev/null +++ b/linux-core/radeon_buffer.c @@ -0,0 +1,129 @@ +/************************************************************************** + *  + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + *  + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + *  + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR  + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + *  + *  + **************************************************************************/ +/* + * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com> + */ + +#include "drmP.h" +#include "radeon_drm.h" +#include "radeon_drv.h" + + +drm_ttm_backend_t *radeon_create_ttm_backend_entry(drm_device_t * dev) +{ +	drm_radeon_private_t *dev_priv = dev->dev_private; + +	if(dev_priv->flags & RADEON_IS_AGP) +		return drm_agp_init_ttm(dev, NULL); +	else +		return ati_pcigart_init_ttm(dev, NULL); +} + +int radeon_fence_types(drm_buffer_object_t *bo, uint32_t * class, uint32_t * type) +{ +	*class = 0; +	if (bo->mem.flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) +		*type = 3; +	else +		*type = 1; +	return 0; +} + +int radeon_invalidate_caches(drm_device_t * dev, uint32_t flags) +{ +	drm_radeon_private_t *dev_priv = dev->dev_private; +	RING_LOCALS; + +	BEGIN_RING(4); +	RADEON_FLUSH_CACHE(); +	RADEON_FLUSH_ZCACHE(); +	ADVANCE_RING(); +	return 0; +} + +uint32_t radeon_evict_mask(drm_buffer_object_t *bo) +{ +	switch (bo->mem.mem_type) { +	case DRM_BO_MEM_LOCAL: +	case DRM_BO_MEM_TT: +		return DRM_BO_FLAG_MEM_LOCAL; +	default: +		return DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_CACHED; +	} +} + +int radeon_init_mem_type(drm_device_t * dev, uint32_t type, +			 drm_mem_type_manager_t * man) +{ +	drm_radeon_private_t *dev_priv = dev->dev_private; + +	switch (type) { +	case DRM_BO_MEM_LOCAL: +		man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | +		    _DRM_FLAG_MEMTYPE_CACHED; +		man->drm_bus_maptype = 0; +		break; +	case DRM_BO_MEM_TT: +		if (dev_priv->flags & RADEON_IS_AGP) { +			if (!(drm_core_has_AGP(dev) && dev->agp)) { +				DRM_ERROR("AGP is not enabled for memory type %u\n", +					  (unsigned)type); +				return -EINVAL; +			} +			man->io_offset = dev->agp->agp_info.aper_base; +			man->io_size = dev->agp->agp_info.aper_size * 1024 * 1024; +			man->io_addr = NULL; +			man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | +				_DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_NEEDS_IOREMAP; +			man->drm_bus_maptype = _DRM_AGP; +		} else { +			man->io_offset = 0; +			man->io_size = dev_priv->gart_size; +			man->io_addr = NULL; +			man->flags = _DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_MEMTYPE_MAPPABLE; +			man->drm_bus_maptype = _DRM_SCATTER_GATHER; +		} +		break; +	default: +		DRM_ERROR("Unsupported memory type %u\n", (unsigned)type); +		return -EINVAL; +	} +	return 0; +} + +int radeon_move(drm_buffer_object_t * bo, +		int evict, int no_wait, drm_bo_mem_reg_t * new_mem) +{ +	drm_bo_mem_reg_t *old_mem = &bo->mem; + +	if (old_mem->mem_type == DRM_BO_MEM_LOCAL) { +		return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); +	} +	return 0; +} + diff --git a/linux-core/radeon_drv.c b/linux-core/radeon_drv.c index 327a6a97..d0995b5b 100644 --- a/linux-core/radeon_drv.c +++ b/linux-core/radeon_drv.c @@ -56,6 +56,38 @@ static struct pci_device_id pciidlist[] = {  	radeon_PCI_IDS  }; + +#ifdef RADEON_HAVE_FENCE +static drm_fence_driver_t radeon_fence_driver = { +	.num_classes = 1, +	.wrap_diff = (1 << 30), +	.flush_diff = (1 << 29), +	.sequence_mask = 0xffffffffU, +	.lazy_capable = 1, +	.emit = radeon_fence_emit_sequence, +	.poke_flush = radeon_poke_flush, +	.has_irq = radeon_fence_has_irq, +}; +#endif +#ifdef RADEON_HAVE_BUFFER + +static uint32_t radeon_mem_prios[] = {DRM_BO_MEM_PRIV0, DRM_BO_MEM_TT, DRM_BO_MEM_LOCAL}; +static uint32_t radeon_busy_prios[] = {DRM_BO_MEM_TT, DRM_BO_MEM_PRIV0, DRM_BO_MEM_LOCAL}; + +static drm_bo_driver_t radeon_bo_driver = { +	.mem_type_prio = radeon_mem_prios, +	.mem_busy_prio = radeon_busy_prios, +	.num_mem_type_prio = sizeof(radeon_mem_prios)/sizeof(uint32_t), +	.num_mem_busy_prio = sizeof(radeon_busy_prios)/sizeof(uint32_t), +	.create_ttm_backend_entry = radeon_create_ttm_backend_entry, +	.fence_type = radeon_fence_types, +	.invalidate_caches = radeon_invalidate_caches, +	.init_mem_type = radeon_init_mem_type, +	.evict_mask = radeon_evict_mask, +	.move = radeon_move, +}; +#endif +  static int probe(struct pci_dev *pdev, const struct pci_device_id *ent);  static struct drm_driver driver = {  	.driver_features = @@ -101,6 +133,13 @@ static struct drm_driver driver = {  		.remove = __devexit_p(drm_cleanup_pci),  	}, +#ifdef RADEON_HAVE_FENCE +	.fence_driver = &radeon_fence_driver, +#endif +#ifdef RADEON_HAVE_BUFFER +	.bo_driver = &radeon_bo_driver, +#endif +  	.name = DRIVER_NAME,  	.desc = DRIVER_DESC,  	.date = DRIVER_DATE, diff --git a/linux-core/radeon_fence.c b/linux-core/radeon_fence.c new file mode 100644 index 00000000..7de3650d --- /dev/null +++ b/linux-core/radeon_fence.c @@ -0,0 +1,125 @@ +/************************************************************************** + *  + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + *  + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + *  + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR  + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + *  + *  + **************************************************************************/ +/* + * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com> + */ + +#include "drmP.h" +#include "drm.h" +#include "radeon_drm.h" +#include "radeon_drv.h" + +/* + * Implements an intel sync flush operation. + */ + +static void radeon_perform_flush(drm_device_t * dev) +{ +	drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; +	drm_fence_manager_t *fm = &dev->fm; +	drm_fence_class_manager_t *fc = &dev->fm.class[0]; +	drm_fence_driver_t *driver = dev->driver->fence_driver; +	uint32_t pending_flush_types = 0; +	uint32_t sequence; + +	if (!dev_priv) +		return; + +	pending_flush_types = fc->pending_flush | +		((fc->pending_exe_flush) ? DRM_FENCE_TYPE_EXE : 0); + +	if (pending_flush_types) { +		sequence = READ_BREADCRUMB(dev_priv); +					      +		drm_fence_handler(dev, 0, sequence, pending_flush_types); +	} + +	return; +} + +void radeon_poke_flush(drm_device_t * dev, uint32_t class) +{ +	drm_fence_manager_t *fm = &dev->fm; +	unsigned long flags; + +	if (class != 0) +		return; + +	write_lock_irqsave(&fm->lock, flags); +	radeon_perform_flush(dev); +	write_unlock_irqrestore(&fm->lock, flags); +} + +int radeon_fence_emit_sequence(drm_device_t *dev, uint32_t class, +			       uint32_t flags, uint32_t *sequence, +			       uint32_t *native_type) +{ +	drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; +	RING_LOCALS; + +	if (!dev_priv) +		return -EINVAL; + +	*native_type = DRM_FENCE_TYPE_EXE; +	if (flags & DRM_RADEON_FENCE_FLAG_FLUSHED) { +		*native_type |= DRM_RADEON_FENCE_TYPE_RW; +		 +		BEGIN_RING(4); +		 +		RADEON_FLUSH_CACHE(); +		RADEON_FLUSH_ZCACHE(); +		ADVANCE_RING(); +	} + +	radeon_emit_irq(dev); +	*sequence = (uint32_t) dev_priv->counter; + + +	return 0; +} + +void radeon_fence_handler(drm_device_t * dev) +{ +	drm_fence_manager_t *fm = &dev->fm; + +	write_lock(&fm->lock); +	radeon_perform_flush(dev); +	write_unlock(&fm->lock); +} + +int radeon_fence_has_irq(drm_device_t *dev, uint32_t class, uint32_t flags) +{ +	/* +	 * We have an irq that tells us when we have a new breadcrumb. +	 */ + +	if (class == 0 && flags == DRM_FENCE_TYPE_EXE) +		return 1; + +	return 0; +} diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index e9c635d7..56d17b9a 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2305,6 +2305,9 @@ int radeon_driver_firstopen(struct drm_device *dev)  	if (ret != 0)  		return ret; +#ifdef RADEON_HAVE_BUFFER +	drm_bo_driver_init(dev); +#endif  	return 0;  } diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index 6a57b804..41fdbf69 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -434,8 +434,17 @@ typedef struct {  	int pfCurrentPage;	/* which buffer is being displayed? */  	int crtc2_base;		/* CRTC2 frame offset */  	int tiling_enabled;	/* set by drm, read by 2d + 3d clients */ + +	unsigned int last_fence;  } drm_radeon_sarea_t; +/* The only fence class we support */ +#define DRM_RADEON_FENCE_CLASS_ACCEL 0 +/* Fence type that guarantees read-write flush */ +#define DRM_RADEON_FENCE_TYPE_RW 2 +/* cache flushes programmed just before the fence */ +#define DRM_RADEON_FENCE_FLAG_FLUSHED 0x01000000 +  /* WARNING: If you change any of these defines, make sure to change the   * defines in the Xserver file (xf86drmRadeon.h)   * diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index f1d9ca9e..c16a43eb 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -104,6 +104,11 @@  #define DRIVER_MINOR		28  #define DRIVER_PATCHLEVEL	0 +#if defined(__linux__) +#define RADEON_HAVE_FENCE +#define RADEON_HAVE_BUFFER +#endif +  /*   * Radeon chip families   */ @@ -278,8 +283,9 @@ typedef struct drm_radeon_private {  	struct mem_block *fb_heap;  	/* SW interrupt */ -	wait_queue_head_t swi_queue; -	atomic_t swi_emitted; +	wait_queue_head_t irq_queue; +	int counter; +  	int vblank_crtc;  	uint32_t irq_enable_reg;  	int irq_enabled; @@ -355,6 +361,7 @@ extern void radeon_mem_release(DRMFILE filp, struct mem_block *heap);  				/* radeon_irq.c */  extern int radeon_irq_emit(DRM_IOCTL_ARGS);  extern int radeon_irq_wait(DRM_IOCTL_ARGS); +extern int radeon_emit_irq(drm_device_t * dev);  extern void radeon_do_release(drm_device_t * dev);  extern int radeon_driver_vblank_wait(drm_device_t * dev, @@ -385,6 +392,30 @@ extern int r300_do_cp_cmdbuf(drm_device_t *dev, DRMFILE filp,  			     drm_file_t* filp_priv,  			     drm_radeon_kcmd_buffer_t* cmdbuf); + +#ifdef RADEON_HAVE_FENCE +/* i915_fence.c */ + + +extern void radeon_fence_handler(drm_device_t *dev); +extern int radeon_fence_emit_sequence(drm_device_t *dev, uint32_t class, +				      uint32_t flags, uint32_t *sequence,  +				    uint32_t *native_type); +extern void radeon_poke_flush(drm_device_t *dev, uint32_t class); +extern int radeon_fence_has_irq(drm_device_t *dev, uint32_t class, uint32_t flags); +#endif + +#ifdef RADEON_HAVE_BUFFER +/* radeon_buffer.c */ +extern drm_ttm_backend_t *radeon_create_ttm_backend_entry(drm_device_t *dev); +extern int radeon_fence_types(struct drm_buffer_object *bo, uint32_t *class, uint32_t *type); +extern int radeon_invalidate_caches(drm_device_t *dev, uint32_t buffer_flags); +extern uint32_t radeon_evict_mask(drm_buffer_object_t *bo); +extern int radeon_init_mem_type(drm_device_t * dev, uint32_t type, +				drm_mem_type_manager_t * man); +extern int radeon_move(drm_buffer_object_t * bo, +		       int evict, int no_wait, drm_bo_mem_reg_t * new_mem); +#endif  /* Flags for stats.boxes   */  #define RADEON_BOX_DMA_IDLE      0x1 @@ -1214,4 +1245,19 @@ do {									\  	write &= mask;						\  } while (0) +/* Breadcrumb - swi irq */ +#define READ_BREADCRUMB(dev_priv) RADEON_READ(RADEON_LAST_SWI_REG) + +static inline int radeon_update_breadcrumb(drm_device_t *dev) +{ +	drm_radeon_private_t *dev_priv = dev->dev_private; + +	dev_priv->sarea_priv->last_fence = ++dev_priv->counter; + +	if (dev_priv->counter > 0x7FFFFFFFUL) +		dev_priv->sarea_priv->last_fence = dev_priv->counter = 1; + +	return dev_priv->counter; +} +  #endif				/* __RADEON_DRV_H__ */ diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c index 5151b4d6..95d8332c 100644 --- a/shared-core/radeon_irq.c +++ b/shared-core/radeon_irq.c @@ -78,7 +78,10 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)  	/* SW interrupt */  	if (stat & RADEON_SW_INT_TEST) { -		DRM_WAKEUP(&dev_priv->swi_queue); +		DRM_WAKEUP(&dev_priv->irq_queue); +#ifdef RADEON_HAVE_FENCE +		radeon_fence_handler(dev); +#endif  	}  	/* VBLANK interrupt */ @@ -105,14 +108,13 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)  	return IRQ_HANDLED;  } -static int radeon_emit_irq(drm_device_t * dev) +int radeon_emit_irq(drm_device_t * dev)  {  	drm_radeon_private_t *dev_priv = dev->dev_private;  	unsigned int ret;  	RING_LOCALS; -	atomic_inc(&dev_priv->swi_emitted); -	ret = atomic_read(&dev_priv->swi_emitted); +	ret = radeon_update_breadcrumb(dev);  	BEGIN_RING(4);  	OUT_RING_REG(RADEON_LAST_SWI_REG, ret); @@ -123,19 +125,19 @@ static int radeon_emit_irq(drm_device_t * dev)  	return ret;  } -static int radeon_wait_irq(drm_device_t * dev, int swi_nr) +static int radeon_wait_irq(drm_device_t * dev, int irq_nr)  {  	drm_radeon_private_t *dev_priv =  	    (drm_radeon_private_t *) dev->dev_private;  	int ret = 0; -	if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr) +	if (READ_BREADCRUMB(dev_priv) >= irq_nr)  		return 0;  	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; -	DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ, -		    RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr); +	DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, +		    READ_BREADCRUMB(dev_priv) >= irq_nr);  	return ret;  } @@ -273,8 +275,8 @@ void radeon_driver_irq_postinstall(drm_device_t * dev)  	drm_radeon_private_t *dev_priv =  	    (drm_radeon_private_t *) dev->dev_private; -	atomic_set(&dev_priv->swi_emitted, 0); -	DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); +	dev_priv->counter = 0; +	DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);  	radeon_enable_interrupt(dev);  } | 
